2016-02-01 13 views
5
#include <stdio.h> 

int main() { 
    printf("sizeof(int): %zu\n", sizeof(int)); 
    printf("%d\n", 2147483648u > -2147483648); 
    printf("%d\n", ((unsigned int)2147483648u) > ((int)-2147483648)); 
    printf("%d\n", 2147483648u != -2147483648); 
    printf("%d\n", ((unsigned int)2147483648u) != ((int)-2147483648)); 
    return 0; 
} 

Der Ausgang dieses Code in C und C++, auf cygwin64 und eine rhel6.4 Maschine mit gcc 5.2.0 ist:Legendes 2^31 und -2^31 integer Förderung

sizeof(int): 4 
1 
0 
1 
0 

Gemäß "Integer promotions" ist 2147483648u vom Typ unsigned int (auch ohne das u Suffix) und -2147483648 vom Typ int (wie üblich). Warum die unterschiedlichen Ergebnisse beim expliziten Casting?

Nach den „Usual arithmetic conversions“, dieser Absatz gilt:

Andernfalls wird die Signedness ist anders: Wenn der Operand mit dem Typ ohne Vorzeichen hat Umwandlung Rang größer oder gleich als der Rang von die Art der der signierte Operanden, dann wird der Operand mit dem signierten Typ ist zum unsigned Typ implizit konvertiert

Dies bedeutet, dass das richtige Ergebnis ist, als ob:

2147483648u > 2147483648u 
2147483648u != 2147483648u 

wurden durchgeführt, weil in 32 Bits, signed -2 ​​^ 31 und unsigned 2^31 die gleiche Darstellung haben. Mit anderen Worten, das Ergebnis beim Casting ist korrekt. Was ist los?

Ich habe das Gefühl, dass irgendwie eine höherrangige Ganzzahl-Promotion ohne Casting angewendet wird, also bekomme ich z. eine 64-Bit-Promotion auf beiden Seiten - aber warum?

Beide ausführbare Dateien sind als 64-Bit kompiliert, kann das eine Rolle spielen?

+0

Bitte wählen Sie eines von C und C++. Diese zwei Sprachen sind unterschiedlich und die Antwort könnte für beide unterschiedlich sein. – fuz

+2

@FUZxxl: Ist in diesem Fall nicht. – DevSolar

+0

Welchen C-Standard kompilieren Sie auch? Behandlung von Integer-Konstanten, die in C11 geändert wurden. – fuz

Antwort

12

Es gibt keine negativen Integer-Konstanten. Es gibt nur positive mit dem unären Operator -.

Seit 2147483648 > INT_MAX, das fördert 2147483648 auf die nächst größere Signed Integer-Typ (weil Sie nicht u hat anhängen), vor die - angewendet wird.


By the way, ist das, warum INT_MIN in der Regel als (-INT_MAX - 1) in <limits.h> definiert ist. ;-)

+1

Wow, das hat mich in 17 Jahren Kodierung in C/C++ nie getroffen :-) – Irfy

+0

In * meinem * Fall habe ich Glück und das ist der Fall. Wie auch immer, win64's long ist 4 Bytes, also wenn ich das mit einem VC Compiler gemacht hätte, wäre das nicht der Fall gewesen. – Irfy

+0

Wenn Sie versuchen, ein Limit zu erreichen, geben Sie -2^63 und -2^127 (berechnet) als Literal ein :) – Irfy