【问题标题】:Operation on ... may be undefined?对 ... 的操作可能未定义?
【发布时间】:2012-05-16 16:51:25
【问题描述】:

我有以下代码

FRAME frameArray[5][10]; // Create the array of frames
int trackBufferFull[5] = {0, 0, 0, 0, 0};// Keeps track of how full the buffer for each node is
int trackFront[5] = {0, 0, 0, 0, 0}; // Array to keep track of which is the front of the array
int trackTail[5] = {0, 0, 0, 0, 0};


// Function to add to the array (CHANGE int frame)
void addFrame (int nodeNumber, FRAME frame)
{
    //Calc tail
    int tail = trackTail[nodeNumber-1];

    // Calc frames in buffer
    int framesinBuffer = trackBufferFull[nodeNumber-1];

    if (framesinBuffer == 10)
    {
        printf("Buffer is full\n");
    }
    else
    {

        // Add frame to frameArray
        frameArray[nodeNumber-1][tail] = frame; 
        printf("\nAdded a frame in node: %i to the buffer\n", nodeNumber);

        // Increment the count
        trackBufferFull[nodeNumber-1]++;
        trackTail[nodeNumber-1] = ++trackTail[nodeNumber-1] % 10;


    }  
}

我用于 frameArray 的数组是长度为 10 的环绕/循环数组,因此我有代码

trackTail[nodeNumber-1] = ++trackTail[nodeNumber-1] % 10;

一切都在独立文件中完美运行,但是在更大的文件中运行时,我收到以下编译错误:

$ cnet GARETH -m 30
compiling gareth.c
gareth.c: In function ‘addFrame’:
gareth.c:77:27: error: operation on ‘trackTail[nodeNumber + -0x00000000000000001]’ may be undefined [-Werror=sequence-point]
gareth.c: In function ‘removeFirstFrame’:
gareth.c:98:28: error: operation on ‘trackFront[nodeNumber + -0x00000000000000001]’ may be undefined [-Werror=sequence-point]
gareth.c:105:1: error: control reaches end of non-void function [-Werror=return-type]
cc1: all warnings being treated as errors

第77行是行

trackTail[nodeNumber-1] = ++trackTail[nodeNumber-1] % 10;

帮助。

要并排查看带有行号的代码和错误,我已将图片上传到: http://i.imgur.com/wyO5a.png

【问题讨论】:

标签: c undefined-behavior


【解决方案1】:

第77行是行

trackTail[nodeNumber-1] = ++trackTail[nodeNumber-1] % 10;

您在sequence points 之间更改trackTail[nodeNumber-1] 两次:一次通过++,一次通过分配。

这是undefined behaviour

补救方法是改写语句,例如:

trackTail[nodeNumber-1] = (trackTail[nodeNumber-1] + 1) % 10;

或者像这样:

trackTail[nodeNumber-1]++;
trackTail[nodeNumber-1] %= 10;

【讨论】:

  • … 或不分:if (++trackTail[nodeNumber-1] > 9) trackTail[nodeNumber-1] = 0;
【解决方案2】:

您正在序列点之间修改trackTail[nodeNumber - 1]。这就像你在分配

i = ++i;

这也是未定义的行为。

把你的代码改成这样:

trackTail[nodeNumber - 1] = (trackTail[nodeNumber - 1] + 1) % 10;

【讨论】:

  • 您提出的解决方案在我看来是错误的。您在一行中将 1 添加到 trackTail[nodeNumer - 1],然后在下一行使用 ++再次递增它。
  • 不。向 tracktail[nodeNumber + 1] 加一不会为其分配增加的值。这就是为什么需要 icrement 的原因。 OP希望对值加一进行模运算,同时希望增加该数组元素的值。
  • 什么?增加的值(模 10)被分配给trackTail[nodeNumer-1],因为那里有一个赋值运算符,其右操作数是增加的值。执行trackTail[nodeNumber - 1] = (trackTail[nodeNumber - 1] + 1) % 10; 行后,trackTail[nodeNumber - 1] 的值肯定是它的前一个值 + 1 模 10。执行后续行后,它将是它的原始值加 2(模 10,除非原始值为 8,其中如果现在是 10)。
【解决方案3】:
trackTail[nodeNumber-1] = ++trackTail[nodeNumber-1] % 10;

是的,正如错误消息所说,这是未定义的行为。在没有序列点的情况下,您不能两次修改相同的值。在这种情况下,这意味着您不能同时使用 ++ 递增 trackTail[nodeNumber-1] 并使用 = 重新分配它。

如果您只使用+ 1 而不是++,它会正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-19
    • 2014-09-13
    相关资源
    最近更新 更多