C言語のenumの大きさは(デフォルトでは)不定

#30844db310b94925a2fab0b7ef6a7adc
2026.6.18
2026.6.18
  • 次のような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) = 4
    • intと同じサイズとなる

  • しかし、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 char or a standard or extended signed or unsigned integer type.

  • 例えば、clangでは-fshort-enumsオプションを付与すると、enumのサイズを強制的に小さくできる。C言語の仕様では、このような挙動は許可されている:

    % clang example.c -fshort-enums
    % ./a.out
    sizeof(Theme) = 1
  • enumのサイズを固定するために、0x7FFFFFFFのようなcharshortでは表現できないメンバを加え、強制的にenumの大きさをint32_t相当にするテクニックがある

  • なお、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対応のコンパイラが必要となる