2013-07-12 8 views
9

Betrachten Sie die folgende C-Anweisungen:Kombination von unären minus und float Umwandlung

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

Ich würde erwarten, dass die unären minus Term einen unsigned long Wert gleich ULONG_MAX und a und b erhalten, um einzelne gesetzt werden und Doppel Präzisionsdarstellungen von ULONG_MAX.

Dies ist das Ergebnis, das ich mit gcc 4.4.7 unter 32-Bit Linux und mit den Intel- und PGI-Compilern unter 64-Bit Linux erhalte. Mit gcc (getestete Versionen 4.4.7, 4.7.2 und 4.8.0, beide mit -O0 und -O2) auf 64-Bit-Linux hat jedoch die doppelte Variable b den erwarteten Wert, aber float a wird gleich -1 stattdessen.

Dagegen sind die folgenden Aussagen sowohl a und b Gleitkommadarstellungen von ULONG_MAX auf allen Compilern und Systeme setzen I getestet:

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

Wenn ich statt unsigned long unsigned int verwenden, erhalte ich die erwartetes Ergebnis auch auf allen Systemen.

Ist dies eine Art von undefiniertem Verhalten oder ein Compilerfehler?

Antwort

6

Dies ist darauf zurückzuführen - die Art Umwandlung geschieht vor der Negation.

Das Problem scheint für eine Weile zu sein. Bug 55771 - Negation and type conversion incorrectly exchanged

In Ihrem zweiten Beispiel findet die Negation vor der Typumwandlung statt. Daher sehen Sie die erwarteten Ergebnisse.

+0

Danke, dass Sie mich auf den Fehlerbericht hingewiesen haben! – chardmeier

+0

Zur Information, clang 3.3 hat dieses Problem nicht (was sehr gcc spezifisch ist). – ouah

5

Was Sie beschreiben, ist ein Compiler-Fehler.

(und es gibt keine undefinierten Verhalten im Programm unter dem Compiler zu entschuldigen) einen Fehler im GCC

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