2012-05-16 10 views
29

Ich habe den folgenden CodeOperation auf ... kann undefiniert sein?

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; 


    } 
} 

Die Arrays I für frameArray verwenden ist ein Wrap-around/zyklische Anordnung der Länge 10, warum also habe ich den Code

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

Alles funktioniert perfekt in ein Standalone-Datei, aber wenn innerhalb einer größeren Datei ausführen, bekomme ich die folgenden Kompilierungsfehler:

$ 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 

Linie 77 ist die Linie

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

Hilfe.

Um den Code mit Zeilennummern und die Fehler nebeneinander zu sehen, habe ich ein Bild hochgeladen: http://i.imgur.com/wyO5a.png

+1

http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points - Sie sind _lucky_ Ihr Compiler warnt Sie dort. – Mat

+1

Eine Frage, die selten auftaucht. +1. –

Antwort

45

Linie 77 ist die Linie

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

Du trackTail[nodeNumber-1] zweimal zwischen sequence points Wechsel: einmal durch ++, und einmal durch Zuordnung.

Dies ist undefined behaviour.

Das Mittel ist die Aussage, zum Beispiel wie so umformulieren:

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

oder etwa so:

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

Vielen Dank, Sie haben es zuerst richtig gelöst. Ich kann jetzt ins Bett gehen :) Ich habe '(trackTail [nodeNumber-1] + 1)% 10;' was H @ CO3 auch bekommen hat, aber kurz nach dir. – gbhall

5

Sie trackTail[nodeNumber - 1] zwischen Sequenzpunkte zu ändern. Es ist, als würden Sie

zuordnen, was auch undefiniertes Verhalten ist.

Ihren Code so etwas wie dies ändern:

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

Ihre vorgeschlagene Lösung sieht für mich falsch aus. Du fügst 1 zu 'trackTail [nodeNumer - 1]' in einer Zeile hinzu und inkrementierst es dann wieder * mit ++ auf der nächsten. – sepp2k

+0

Nein. Hinzufügen von eins zu TrackTail [Knotennummer + 1] weist ihm den erhöhten Wert NICHT zu. Deshalb wird die Lösung benötigt.OP möchte, dass der Modulo auf dem Wert * plus eins * ausgeführt wird, und gleichzeitig den Wert dieses Array-Elements erhöhen möchte. –

+1

Was? Der inkrementierte Wert (Modulo 10) wird 'trackTail [nodeNumer-1]' zugewiesen, da dort ein Zuweisungsoperator existiert, dessen rechter Operand der inkrementierte Wert ist. Nach dem Ausführen der Zeile "trackTail [nodeNumber - 1] = (trackTail [nodeNumber - 1] + 1)% 10;' ist der Wert von 'trackTail [nodeNumber - 1]' definitiv der vorherige Wert + 1 modulo 10. Nach der Ausführung In der folgenden Zeile ist es der ursprüngliche Wert plus 2 (Modulo 10, es sei denn, der ursprüngliche Wert war 8, in diesem Fall ist es jetzt 10). – sepp2k

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

Yep, das ist nicht definiertes Verhalten ebenso wie die Fehlermeldung sagt. Sie dürfen den gleichen Wert nicht zweimal ohne einen Sequenzpunkt dazwischen ändern. In diesem Fall bedeutet dies, dass Sie nicht beide trackTail[nodeNumber-1] mit ++ inkrementieren und neu zuweisen können, indem Sie = verwenden. Wenn Sie einfach + 1 anstelle von ++ verwenden, wird es problemlos funktionieren.

+0

Vielen Dank sepp. – gbhall

Verwandte Themen