W pierwszej instancji sam kompilator próbuje wybrać liczbę całkowitą, która powoduje przepełnienie, a więc ostrzega. Prawdopodobnie produkuje INT_MIN
. Standard pozwala, aby dowolna wartość w signed int
była stała enum (patrz na dole).
W drugim wyrażeniu (INT_MAX + 1)
oblicza się przed przypisaniem do out_2
. Przepełnienie wyrażenia tutaj daje wynik, który jest dozwolony, ale jest to niezdefiniowane zachowanie. Prawidłowy wynik jest następnie zapisywany w wyliczeniu, dlatego pierwszy błąd nie jest generowany.
szczęk (3.2) również nie ostrzega o tym, co jest praktycznie identyczne:
int a = INT_MAX + 1;
Pod tym względem szczęk nie zachowuje się zgodnie ze standardem C, ponieważ jest zdefiniowana.
Wyjście z gcc w porównaniu czyni różnicę całkowicie jasne:
In function ‘main’:
9:9: error: overflow in enumeration values
13:25: warning: integer overflow in expression [-Woverflow]
Intel Kompilator ignoruje przepełnienie enum, ale ostrzega o przepełnienie liczby całkowitej:
enum.c(13): warning #61: integer operation result is out of range
out_2 = INT_MAX + 1
^
odsyłającym ze standardu C99 6.7.7.2.2, "Wyrażenie określające wartość stałej wyliczeniowej musi być wyrażeniem stałym w postaci liczby całkowitej, które ma wartość reprezentowalną jako
int
; .3," T Identyfikatory na liście wyliczeniowej są zadeklarowane jako stałe, które mają typ
int
i mogą pojawić się tam, gdzie są one dozwolone. "tj. stała wyliczeniowa może być dowolną wartością
int
i ma typ
int
. Wynikowy typ zdefiniowanej zmiennej wyliczeniowej może być
char
,
int
lub
unsigned int
, o ile pozwala na wszystkie możliwe stałe w wyliczeniu. W związku z tym zarówno
enums
w tym przykładzie są niezdefiniowane, ponieważ oba wymagają przepełnienia liczby całkowitej. Pierwszy jest wyraźnie nielegalny.
Jestem pewien, że standard nie definiuje zakresu "wyliczenia". – asveikau
Moje przypuszczenie: najpierw ocenia INT_MAX + 1, które zawija i przypisuje je do out_2. –
@johnny: nie, wywołuje UB. –