2012-05-16 13 views
29

I tienen el siguiente código deOperación en ... ¿puede estar indefinido?

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; 


    } 
} 

Las matrices que utilizo para frameArray es un wrap-around/disposición cíclica de longitud 10, por lo tanto, por qué tengo el código

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

Todo funciona perfectamente en una archivo independiente, sin embargo cuando se ejecuta dentro de un archivo más grande, consigo los siguientes errores de compilación:

$ 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 

línea 77 es la línea

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

Ayuda.

para ver el código con los números de línea y el lado a lado errores, he subido una imagen para: http://i.imgur.com/wyO5a.png

+1

http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points - eres _lucky_ tu compilador te avisa allí. – Mat

+1

Una pregunta que rara vez se plantea. +1. –

Respuesta

45

línea 77 es la línea

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

Está cambiando trackTail[nodeNumber-1] dos veces entre sequence points: una vez a través ++, y una vez a través asignación.

Esto es undefined behaviour.

El remedio es volver a redactar la declaración, por ejemplo, así:

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

o así:

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

Muchas gracias, primero lo resolvió correctamente. Puedo irme a la cama ahora :) He usado '(trackTail [nodeNumber-1] + 1)% 10;' que H @ CO3 también obtuvo, pero poco después. – gbhall

5

Usted está modificando trackTail[nodeNumber - 1] entre los puntos de secuencia. Es como si estuviera asignando

i = ++i; 

que también es un comportamiento indefinido.

cambiar el código para algo como esto:

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

Su solución propuesta me parece incorrecta. Está agregando 1 a 'trackTail [nodeNumer - 1]' en una línea y luego incrementándolo * nuevamente * usando ++ en la siguiente. – sepp2k

+0

No. Agregar uno a tracktail [nodeNumber + 1] NO le asigna el valor incrementado. Es por eso que el helado es necesario.OP quiere que el módulo se realice en el valor * más uno *, y al mismo tiempo quiere aumentar el valor de ese elemento de la matriz. –

+1

¿Qué? El valor incrementado (módulo 10) se asigna a 'trackTail [nodeNumer-1]' porque hay un operador de asignación allí cuyo operando derecho es el valor incrementado. Después de ejecutar la línea 'trackTail [nodeNumber - 1] = (trackTail [nodeNumber - 1] + 1)% 10;' el valor de 'trackTail [nodeNumber - 1]' será definitivamente su valor anterior + 1 módulo 10. Después de ejecutar la línea subsecuente, será su valor original más 2 (módulo 10 a menos que el valor original fuera 8, en cuyo caso ahora será 10). – sepp2k

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

Sí, eso es un comportamiento indefinido como dice el mensaje de error. No está permitido modificar el mismo valor dos veces sin un punto de secuencia en el medio. En este caso, eso significa que no puede aumentar trackTail[nodeNumber-1] usando ++ y reasignarlo usando =.

Si solo usa + 1 en lugar de ++, funcionará bien.

+0

Muchas gracias sepp. – gbhall

Cuestiones relacionadas