[英]Overflow of an enum type in C?
如果我有枚舉類型,例如:
enum week{ sunday=0, monday, tuesday, wednesday, thursday, friday, saturday};
我有:
enum week day;
day = saturday;
day++;
一天的價值是多少?
枚舉類型本質上是一個命名的整數值。 枚舉類型與可以表示所有命名值的基礎整數類型相關聯。 底層整數類型需要能夠表示所有唯一的命名值,但其實際類型是實現定義的。
在這種情況下, saturday
的數值將是6
。 遞增它將給出數值7
。 實際上,這不太可能溢出底層整數類型( int
, char
, unsigned char
或編譯器選擇的任何內容),因此使用%d
格式打印值將打印7
。
但是, enum week
類型的enum week
(命名)值沒有值,值為7
。
如果遞增枚舉值會溢出底層整數類型(這不是這里的情況),結果是未定義的。 這是因為底層整數類型可以是有符號或無符號的,並且溢出有符號整數類型會給出未定義的行為。
從理論上講,編譯器可能會使用enum week
的基礎類型,它只能表示0
到6
的值 - 在這種情況下,遞增saturday
會給出未定義的行為。 在實踐中,AFAIK還沒有任何C編譯器不選擇基礎類型作為標准整數類型之一( char
, int
, unsigned char
, unsigned
等)。 所有這些類型都可以表示7
的數值。
我只能找到C89規范的草稿,而且我不是C專家,所以我可能會誤解它。 但其第3.5.2.2節說明了這一點
枚舉器列表中的標識符聲明為具有int類型的常量,並且可以出現在允許的位置。 [...]每個枚舉類型應與整數類型兼容。
我認為這意味着day++
總會在這里產生7
(比saturday
代表的值多一個)。
鑒於:
enum week {
sunday=0, monday, tuesday, wednesday, thursday, friday, saturday
};
enum week day = saturday;
day ++;
day
的價值是7
。
引用2011 ISO C標准,6.7.2.2第1段:
每個枚舉類型應與
char
,有符號整數類型或無符號整數類型兼容。 類型的選擇是實現定義的,但應能夠表示枚舉的所有成員的值。
_Bool
是無符號整數類型,但它不符合此特定枚舉類型的要求。
由於CHAR_BIT
的值必須至少為8
,並且char
, unsigned char
和signed char
類型不需要填充位,因此每種字符類型的范圍必須至少涵蓋0
到127
。 更寬的整數類型( short
, int
等)的范圍至少與signed char
或unsigned char
范圍一樣寬。 因此,與enum week
兼容的實現定義類型必須具有不大於0
的下限,並且上限不小於127
。
( 警告 :隨后是語言律師。)可能存在一個漏洞,允許擴展的整數類型 ,其范圍比_Bool
更寬,但范圍比char
更窄。 例如,我認為一個大小為8位但只有3位值的擴展整數類型是合法的。 但由於需要使用整數類型來表示二進制表示,因此具有3個值位的無符號類型將能夠表示0到7的值,而具有2個值位的無符號類型將無法表示saturday
的值。 由於enum week
可以保持值6
,因此它還必須能夠保持值7
。 在一個不尋常的實現中,它可能無法表示值8
,但您不太可能遇到這樣的實現。
基本上,考慮到整數類型使用純二進制表示的要求,任何可以表示6
類型也可以表示7
,盡管它不會自動遵循它也可以表示8
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.