枚舉類型的優勢
枚舉類型完全可被宏定義替代,類如
enum Furniture {
DOOR = 1,
DESK,
LOCK,
}
與下面的代碼等效
#define DOOR 1
#define DESK 2
#define LOCK 3
那么我們如何在兩種設計方法中選擇呢?在我看來某些情況下使用enum會有以下優勢:
- 提高代碼鍵入效率;僅適用於所需變量的值是連續的整數,就像上面的情況,可以只給第一個DOOR賦值,其余的值累加。如果首個變量的值要求是0,甚至每一個都無需顯式賦值
- 提高代碼的可維護性;可以划定范圍,編譯器也會檢查類型是否正確,偶爾會有用
- 提高代碼的可讀性;例如 DOOR, DESK, LOCK... 都屬於家具,均定義在Furniture中
枚舉類型所占的大小
枚舉類型所占內存的大小,即枚舉變量的大小。
由於枚舉變量的賦值,一次只能存放枚舉結構中的某個常數。所以 枚舉變量的大小,實質是常數所占內存空間的大小(常數為int類型,當前主流的編譯器中一般是32位機器和64位機器中int型都是4個字節),枚舉類型所占內存大小也是這樣。
所以默認情況下,無論枚舉變量的值是多少,都是占用 4 個字節。即執行:
printf("sizeof(enum Furniture) = %d\n", sizeof(enum Furniture));
輸入的結果是 4。
編譯選項:-fshort-enums
GCC下關於這個編譯選項的介紹:
-fshort-enums
Allocate to an enum type only as many bytes as it needs for the declared range of possible values. Specifically, the enum type is equivalent to the smallest integer type that has enough room.
Warning: the -fshort-enums switch causes GCC to generate code that is not binary compatible with code generated without that switch. Use it to conform to a non-default application binary interface.
意思是說使用-fshort-enum
s后,對改枚舉類型所占空間的分配就會按照實際變量的占用空間,而非總是4字節。
啟用該選項之后,再打印它的size就會是1,因為用1個字節就能表示所有枚舉變量的值(DOOR=1,DESK=2,LOCK=3).
這個“1”不再是固定的,根據其中枚舉變量值的不同,動態調整enum Furniture
的大小。
enum Furniture {
DOOR = 256,
DESK,
LOCK,
}
再打印它的size,結果為2。因為值256無法用1個字節存下。
潛在的問題
看似好像啟用該選項會節約一定的內存空間,是的。但它也有一定的缺點,其一就是可移植性問題。
例如你編寫的應用在編譯時沒有啟用了該“優化”選項,默認采用4字節存儲枚舉變量。而鏈接的庫文件在編譯時卻使用了“優化”選項,則庫內部此枚舉類型的大小可能為1字節。若此時恰好你有調用某個庫API,將emun變量作為參數進行傳遞,那么就會發生錯誤。
為避免不同庫和應用程序使用“優化”選項的差異造成潛在的危險,常用的解決方案是強制使enum變量占用4個字節,無論其是否開啟“優化”。實現方式是在enum變量末尾添加一個成員 XXXX_END = 0xFFFFF
,例如:
enum Furniture {
DOOR = 1,
DESK,
LOCK,
END = 0xFFFFF,
}