#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;
}
Wyjście tego kodu zarówno C i C++, w cygwin64 i urządzenie rhel6.4 z gcc 5.2.0 jest:Zrozumienie 2^31^31 i -2 całkowitą promowanie
sizeof(int): 4
1
0
1
0
Zgodnie z "Integer promotions", 2147483648u
będzie typu unsigned int
(nawet bez sufiksu u
) i -2147483648
typu int
(jak zwykle). Dlaczego różne wyniki z wyraźnym castingiem?
Według „Usual arithmetic conversions”, ustęp ten ma zastosowanie:
Inaczej, uzyskiwany znak jest inny: Jeśli operand z typu unsigned ma większą rangę konwersji lub równa randze rodzaj podpisany argumentu, a operand z zawartą typu niejawnie przeprowadzono w unsigned
oznacza to, że prawidłowy wynik jest, gdy:
2147483648u > 2147483648u
2147483648u != 2147483648u
zostały wykonane, ponieważ w 32 bitach, podpisane -2^31 i bez znaku 2^31 mają tę samą reprezentację. Innymi słowy, wynik rzucania jest poprawny. Co się dzieje?
Mam wrażenie, że w jakiś sposób promocja liczb całkowitych o wyższej randze jest stosowana bez przesyłania, więc otrzymuję np. 64-bitowa podpisana promocja po obu stronach - ale dlaczego?
Oba pliki wykonywalne są skompilowane jako 64-bitowe, czy może to odgrywać rolę?
Proszę wybrać jedną z C i C++. Te dwa języki są różne i odpowiedź może być inna dla obu. – fuz
@FUZxxl: W tym przypadku nie jest. – DevSolar
Poza tym, z którym typem C kompilujesz? Obsługa stałych całkowitych została zmieniona w C11. – fuz