Rozważmy następujące instrukcje C:połączenie jednoargumentowy minus i pływaka konwersji
unsigned long x = 1;
float a = -x;
double b = -x;
Oczekiwałbym jednoargumentowy minus Określenie otrzymując unsigned long wartość równą ULONG_MAX a A i B będą ustawione na pojedyncze i podwójne precyzyjne reprezentacje ULONG_MAX, odpowiednio.
Jest to wynik, który otrzymuję z gcc 4.4.7 na 32-bitowym systemie Linux oraz z kompilatorami Intel i PGI na 64-bitowym systemie Linux. W przypadku gcc (wersje testowane 4.4.7, 4.7.2 i 4.8.0, obie z -O0 i -O2) w 64-bitowym systemie Linux, podwójna zmienna b ma oczekiwaną wartość, ale zmienna a staje się równa -1 zamiast.
Natomiast następujące stwierdzenia ustawi A i B do pływających reprezentacje punktowych ULONG_MAX wszystkich kompilatorów i systemów testowałem:
unsigned long x = 1;
unsigned long y = -x;
float a = y;
double b = y;
Jeśli używam unsigned int zamiast unsigned long, otrzymuję oczekiwany wynik na wszystkich systemach.
Czy jest to niezdefiniowane zachowanie lub błąd kompilatora?
Dzięki za skierowanie mnie do zgłoszenia błędu! – chardmeier
Dla informacji, clang 3.3 nie ma tego problemu (który jest bardzo specyficzny dla gcc). – ouah