2011-02-02 70 views
21

已經通過this related question讀取,但正在尋找一些更具體的東西。在C中指定枚舉類型的大小

  • 有沒有辦法告訴你的編譯器具體有多寬你想要你的枚舉?
  • 如果是這樣,你是如何做到的?我知道如何在C#中指定它;它在C中類似嗎?
  • 它會值得嗎?當枚舉值傳遞給一個函數時,它是否會作爲一個int大小的值傳遞,無論?

回答

14

有沒有辦法告訴你的編譯器 明確你想要多寬的 枚舉呢?

一般情況下沒有。不在標準C中。

它會值得嗎?

這取決於上下文。如果你正在討論傳遞函數的參數,那麼不,這是不值得的(見下文)。如果是從枚舉類型構建聚合時節省內存,那麼它可能是值得的。但是,在C中,您可以簡單地使用合適大小的整數類型,而不是聚合中的枚舉類型。在C中(與C++相反),枚舉類型和整數類型幾乎總是可以互換的。

當枚舉值被傳遞給一個函數時,它會作爲一個int大小的值傳遞嗎?

現在很多(大多數)編譯器都將所有參數作爲給定硬件平臺的自然字大小值。例如,在64位平臺上,即使類型int在該平臺上有32位,許多編譯器都會將所有參數作爲64位值傳遞,而不管它們的實際大小如何(因此,它通常不會以「int這種平臺上的「價值」)。出於這個原因,嘗試優化枚舉大小以實現參數傳遞是沒有意義的。

8

通過定義合適的值,可以強制它至少達到一定的大小。例如,如果你希望你的枚舉將被存儲爲相同的尺寸爲int,即使所有的值將適合在char,你可以做這樣的事情:

typedef enum { 
    firstValue = 1, 
    secondValue = 2, 

    Internal_ForceMyEnumIntSize = MAX_INT 
} MyEnum; 

但是請注意,該行爲可能取決於實施。如你所說,傳遞這樣一個值到一個函數會導致它被擴展爲一個int,但是如果你在一個數組或結構中使用你的類型,那麼它的大小就會很重要。如果你真的關心元素大小,你應該真的使用類型,如int8_t,int32_t

+1

這就是我的想法。我傾向於定義一些枚舉實際上不需要超過8或16位,並且當我不需要時我討厭浪費空間。 – Will 2011-02-02 20:16:43

+0

如果優化器刪除未使用的`Internal_ForceMyEnumIntSize`,則這可能不起作用 – EBlake 2017-01-25 23:47:21

+0

@KJohnson Is Internal_ForceMyEnumIntSize是否爲C關鍵字? – Patrick 2017-03-19 06:42:30

11

我相信有一個標誌,如果你使用GCC。

-fshort-枚舉

+0

+1 Cool ...這就是我一直在強迫編譯器去尋找的東西。 – Will 2011-02-02 20:14:30

-12

另一種方式是蒙上了工會內部的枚舉如下:

union char_size { 
    char a; 
    enum { 
    a = 1, 
    b = 2, 
    } val; 
}; 

否則將強制編譯器,以適應一個字符內的枚舉。

6

也有另一種方式,如果枚舉是一個結構的一部分:

struct something { 
    :0; 
    enum whatever field:CHAR_BIT; 
    :0; 
}; 

的:0;如果枚舉字段被普通字段包圍,則可以省略。如果之前還有另一個位域,則:0將強制字節對齊到下一個字段的下一個字節。

0

它取決於爲枚舉指定的值。

例如: 如果存儲大於2^32-1的值,則爲整個枚舉分配的大小將更改爲下一個大小。

將0xFFFFFFFFFFFF值存儲到枚舉變量中,如果試圖在32位環境中編譯時會發出警告(四捨五入警告) 在64位編譯中,它將成功並且分配的大小爲8字節。