54

I have the following code

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;


    }  
}

The arrays I use for frameArray is a wrap-around/cyclic array of length 10, hence why I have the code

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

Everything works perfectly in a standalone file, however when run inside of a larger file, I get the following compile errors:

$ 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

Line 77 is the line

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

Help.

To see the code with line numbers and the errors side by side, I've uploaded an image to: https://i.stack.imgur.com/lLPnX.png

Suraj Jain
  • 4,463
  • 28
  • 39
gbhall
  • 13,139
  • 9
  • 37
  • 42
  • 3
    http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points - you're _lucky_ your compiler warns you there. – Mat May 16 '12 at 16:54

3 Answers3

78

Line 77 is the line

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

You are changing trackTail[nodeNumber-1] twice between sequence points: once through ++, and once through assignment.

This is undefined behaviour.

The remedy is to rephrase the statement, for example like so:

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

or like so:

trackTail[nodeNumber-1]++;
trackTail[nodeNumber-1] %= 10;
Community
  • 1
  • 1
NPE
  • 486,780
  • 108
  • 951
  • 1,012
10

You're modifying trackTail[nodeNumber - 1] between sequence points. It's like you're assigning

i = ++i;

which is also undefined behaviour.

Change your code to something like this:

trackTail[nodeNumber - 1] = (trackTail[nodeNumber - 1] + 1) % 10;
  • Your proposed solution looks wrong to me. You're adding 1 to `trackTail[nodeNumer - 1]` on one line and then incrementing it *again* using ++ on the next. – sepp2k May 16 '12 at 16:58
  • Nope. Adding one to tracktail[nodeNumber + 1] does NOT assign the incremented value to it. That's why the icrement is needed. OP wants the modulo to be performed on the value *plus one*, and at the same time wants to increase the value of that array element. –  May 16 '12 at 16:58
  • 1
    What? The incremented value (modulo 10) is assigned to `trackTail[nodeNumer-1]` because there's an assignment operator there whose right operand is the incremented value. After executing the line `trackTail[nodeNumber - 1] = (trackTail[nodeNumber - 1] + 1) % 10;` the value of `trackTail[nodeNumber - 1]` will definitely be its previous value + 1 modulo 10. After executing the subsequent line, it will be its original value plus 2 (modulo 10 unless the original value was 8, in which case it will now be 10). – sepp2k May 16 '12 at 17:01
6
trackTail[nodeNumber-1] = ++trackTail[nodeNumber-1] % 10;

Yep, that's undefined behavior just as the error message says. You're not allowed to modify the same value twice without a sequence point in between. In this case that means you're not allowed to both increment trackTail[nodeNumber-1] using ++ and reassign it using =.

If you just use + 1 instead of ++, it will work fine.

sepp2k
  • 363,768
  • 54
  • 674
  • 675