【C言語 enum】
列挙型の型は?符号は?
一足お先にC23仕様の使い方

最終更新日 2025年11月14日

warning: result of comparison of unsigned enum expression < 0 is always false

警告:unsigned enum 式 < 0 の比較結果は常に偽である。
[-Wtautological-unsigned-enum-zero-compare]

■この記事の概要

C言語のenum型の符号に関し、メンバーに負値がない場合の符号無し(unsigned)化と、その逆のケースについて解説。

符号に応じた挙動の違いや、予期せぬバグの防止策を紹介します。


■enumのメンバーに負値が無いと符号無し(unsigned)

#include    <stdio.h>
typedef enum {
    A=0,//符号なしになる
    B,
    C}  
typeA ;//負値無しのenum型

int main(void){
    typeA  x = -1;
    if(x >= 0){
        puts("符号なし!こちらが表示されます");
    }else{
        puts("符号付き");
    }
}

enum型はメンバ内の負値の有無に応じて
符号付きになったり、
符号無しになったりします。

enumのメンバに負値がない場合
enumの型はgcc,clangでは
type A xは
符号無しになりました。
このためxは負値にならないのでif文は成立します。

■enumのメンバーに負値が有ると符号付き(signed)

#include    <stdio.h>
typedef enum {
    A=-1,//符号付きになる
    B,
    C}  
typeA ;//負値ありのenum型

int main(void){
    typeA  x = -1;
    if(x >= 0){
        puts("符号なし");
    }else{
        puts("符号付き!こちらが表示されます");
    }
}

enumのメンバに負値がある場合
enumの型はgcc,clangでは
type A xは
符号付きになりました。
このためxは負値になるのでif文は成立しません。

■型指定ができるC23仕様のenum型の定義

#include <stdio.h>
typedef enum : unsigned char    { 
    赤, 緑, 青 
} 色;       // C23以降
typedef enum : signed int       { 
    不可 = -1, 可,良,優
} 成績;     // C23以降

int main(void){
    printf("%zu\n",sizeof(色));
    printf("%zu\n",sizeof(成績));
}

gcc 13.3版でコンパイルできました。

参考:

INT09-C. 列挙定数が一意の値に対応することを保証する