2012-05-16 12 views
29

Ho il seguente codiceL'operazione su ... potrebbe essere indefinita?

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; 


    } 
} 

Gli array che uso per frameArray è un avvolgente/array ciclico di lunghezza 10, quindi, perché ho il codice

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

Tutto funziona perfettamente in un file autonomo, tuttavia quando eseguito all'interno di un file di dimensioni maggiori, ottengo i seguenti errori di compilazione:

$ 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 

linea 77 è la linea

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

Help.

per vedere il codice con numeri di riga e il lato gli errori a fianco, ho caricato un'immagine: http://i.imgur.com/wyO5a.png

+1

http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points - you're _lucky_ il compilatore ti avvisa. – Mat

+1

Una domanda che si pone raramente. +1. –

risposta

45

linea 77 è la linea

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

State cambiando trackTail[nodeNumber-1] due volte tra sequence points: una volta attraverso ++, e una volta attraverso assegnazione.

Questo è undefined behaviour.

Il rimedio è quello di riformulare la dichiarazione, ad esempio in questo modo:

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

o in questo modo:

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

Grazie mille, per prima cosa l'hai risolto correttamente. Ora posso andare a letto :) Ho usato '(trackTail [nodeNumber-1] + 1)% 10;' che anche H @ CO3 ha ottenuto, ma poco dopo. – gbhall

5

si sta modificando trackTail[nodeNumber - 1] tra i punti di sequenza. È come se stessi assegnando

i = ++i; 

che è anche un comportamento non definito.

modificare il codice a qualcosa di simile:

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

La tua soluzione proposta mi sembra sbagliata. Stai aggiungendo 1 a 'trackTail [nodeNumer - 1]' su una riga e quindi incrementandolo * di nuovo * usando ++ al successivo. – sepp2k

+0

No. Aggiungendo uno a tracktail [nodeNumber + 1] NON assegna ad esso il valore incrementato. Ecco perché è necessario l'icrement.OP vuole che il modulo venga eseguito sul valore * più uno *, e allo stesso tempo vuole aumentare il valore di quell'elemento di matrice. –

+1

Cosa? Il valore incrementato (modulo 10) è assegnato a "trackTail [nodeNumer-1]" perché è presente un operatore di assegnazione il cui operando destro è il valore incrementato. Dopo aver eseguito la riga 'trackTail [nodeNumber - 1] = (trackTail [nodeNumber - 1] + 1)% 10;' il valore di 'trackTail [nodeNumber - 1]' sarà sicuramente il suo valore precedente + 1 modulo 10. Dopo l'esecuzione la riga successiva, sarà il suo valore originale più 2 (modulo 10 a meno che il valore originale fosse 8, nel qual caso sarà 10). – sepp2k

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

Sì, è un comportamento indefinito come il messaggio di errore dice. Non ti è permesso modificare lo stesso valore due volte senza un punto di sequenza intermedio. In questo caso, ciò significa che non è consentito ad entrambi incrementare ++ utilizzando ++ e riassegnarlo utilizzando =.

Se si utilizza + 1 anziché ++, funzionerà correttamente.

+0

Grazie mille sepp. – gbhall

Problemi correlati