C言語のenumの大きさは(デフォルトでは)不定
次のようなenumを考える。この出力はどうなるだろうか:
example.c#include <stdio.h> typedef enum Theme { LIGHT, DARK, SYSTEM_DEFAULT, } Theme; int main() { printf("sizeof(Theme) = %zu\n", sizeof(Theme)); return 0; }Apple clang (21.0.0)でオプションを与えずにコンパイルして実行すると
% clang example.c % ./a.out sizeof(Theme) = 4intと同じサイズとなる
しかし、C23の時点で、enumの型が明示されていない場合、その大きさに関しては具体的な指定がない
N3096 p126
All enumerations have an underlying type. The underlying type can be explicitly specified using an enum type specifier and is its fixed underlying type. If it is not explicitly specified, the underlying type is the enumeration’s compatible type, which is either
charor a standard or extended signed or unsigned integer type.
例えば、clangでは
-fshort-enumsオプションを付与すると、enumのサイズを強制的に小さくできる。C言語の仕様では、このような挙動は許可されている:% clang example.c -fshort-enums % ./a.out sizeof(Theme) = 1enumのサイズを固定するために、
0x7FFFFFFFのようなcharやshortでは表現できないメンバを加え、強制的にenumの大きさをint32_t相当にするテクニックがある例えば
typedef enum Theme { LIGHT, DARK, SYSTEM_DEFAULT, FORCE32 = 0x7FFFFFFF, } Theme;とすると、
% clang example.c -fshort-enums % ./a.out sizeof(Theme) = 4webgpu.hなどで見られる:
なお、C23ではenumに明示的に型を指定することができる:
typedef enum Theme : int { LIGHT, DARK, SYSTEM_DEFAULT, } Theme;この場合、enumの大きさは
-fshort-enumsの影響を受けない:% clang example.c -fshort-enums % ./a.out sizeof(Theme) = 4ただし、当然ながらC23対応のコンパイラが必要となる