2013-07-12 24 views
9

galleggiante Considerate le seguenti istruzioni C:combinazione di unario e conversione

unsigned long x = 1; 
float a = -x; 
double b = -x; 

ci si aspetterebbe il termine meno unario per produrre un valore lungo senza segno uguale ULONG_MAX e a e b essere impostato a singolo e doppio rappresentazioni di precisione di ULONG_MAX, rispettivamente.

Questo è il risultato che ottengo con gcc 4.4.7 su Linux a 32 bit e con i compilatori Intel e PGI su Linux a 64 bit. Con gcc (versioni testate 4.4.7, 4.7.2 e 4.8.0, entrambe con -O0 e -O2) su Linux 64-bit, tuttavia, la doppia variabile b ha il valore atteso, ma float a diventa uguale a -1 anziché.

Per contro, le istruzioni seguenti imposteranno sia a che b a variabile rappresentazioni puntuali di ULONG_MAX su tutti i compilatori e sistemi I testati:

unsigned long x = 1; 
unsigned long y = -x; 
float a = y; 
double b = y; 

Se uso int unsigned anziché lungo senza segno, ottengo il risultato atteso su tutti i sistemi.

Si tratta di una sorta di comportamento non definito o di un errore del compilatore?

risposta

6

Ciò è dovuto ad un bug nel GCC - la conversione di tipo avviene prima della negazione.

Il problema sembra essere stato in giro per un po '. Bug 55771 - Negation and type conversion incorrectly exchanged

Nel secondo esempio, la negazione si verifica prima della conversione del tipo. Come tale, vedi i risultati attesi.

+0

Grazie per avermi segnalato il bug report! – chardmeier

+0

Per informazioni, clang 3.3 non ha questo problema (che è molto specifico per gcc). – ouah

5

Quello che descrivi è un bug del compilatore.

(e non v'è alcun comportamento non definito nel programma di seguito per giustificare il compilatore)

unsigned long x = 1; 
float a = -x; 
double b = -x;