2012-08-06 14 views
5

Eventuali duplicati:
GCC left shift overflowimprevisto sinistra-shift comportamento

Si consideri il seguente programma minimo.

#include <stdint.h> 
#include <stdio.h> 

int main() 
{ 
    uint32_t v = 1024; 
    v &= (((uint32_t)1 << 32) - 1); 
    printf("v = %u\n", v); 
    return 0; 
} 

Questo stampa 1024 come avrei aspettavo la compilazione con GCC sotto MinGW. Perché 1 spostato 32 volte a sinistra è di nuovo 0, quindi 0-1 = -1 che è "1111 .... 1111". Questo AND'ed con qualsiasi valore dovrebbe restituire lo stesso valore di nuovo.

Tuttavia, se cambio il programma per

#include <stdint.h> 
#include <stdio.h> 

int main() 
{ 
    unsigned int s = 32; 
    uint32_t v = 1024; 
    v &= (((uint32_t)1 << s) - 1); 
    printf("v = %u\n", v); 
    return 0; 
} 

Il risultato stampato è ora 0. Qualcuno può spiegare questo comportamento?

risposta

7

Spostare un valore a 32 bit di 32 bit non è un comportamento non definito in C. Non farlo.

+0

http://catb.org/jargon/html/N/nasal-demons.html –

6

Entrambi sono comportamenti non definiti, poiché la distanza di spostamento deve essere inferiore alla larghezza del bit del tipo. Con la costante, l'ottimizzatore di gcc fa quello che ti aspetti, ma con la variabile, lo spostamento viene eseguito in fase di esecuzione. Probabilmente la distanza di spostamento è mascherata da 31, quindi non è stato effettuato nessuno spostamento e 1 - 1 == 0.

Problemi correlati