【C言語】
switch(狭い型)
case 大き過ぎ

warning: case label value exceeds maximum value for type

警告:caseの値が型の最大値を超えています
[-Wswitch-outside-range]


■この記事の概要

この記事では、C言語でswitch文に狭い型(charshort)を使用する問題を解説しています。これらの型ではcase値が型の範囲を超える場合、誤動作や警告が発生する可能性があります。代わりにintenum型を使用することで、可読性と安全性を向上させる方法が具体例を交えて説明されています。

■switch(char 型)を避ける

#include    <stdio.h>
#include    <stdint.h>
#include    <limits.h>

//switch式には コンパイラ依存の多い char 型を避ける
void    f1(char x)
{
    switch(x){
  case -129:	printf("表現できない\n");   break; 
  case -128:	printf("表現できないかも\n");break; 
    case -127:	printf("コンパイラ依存\n"); break; 
    case -1:	printf("コンパイラ依存\n"); break;
    case 128:	printf("コンパイラ依存\n"); break;
    case 255:	printf("コンパイラ依存\n"); break;
    case 256:	printf("表現できない\n");   break;
    }
}

char型は
符号付きか
符号無しかコンパイラに依存し
扱える最大値が異なるため、
switch(式)に使うのは適切ではありません。

unsigned char 型で256や-1を表現できません。
signed char型では-129や128を表現できません。


switch(式)には
char型ではなくて、
enum型が適切です。


switch(unsigned char型)も避ける

//時給計算には 255円しか表現できない unsigned char を避ける
typedef unsigned char U1 ;
void    f2(U1 x)
{
    switch(x){
    case UCHAR_MAX:             printf("255\n");      break;
    case 955:	printf("愛知最低賃金時間額(円)\n");   break; 
    case 902:	printf("三重最低賃金時間額(円)\n");   break;
    case 896:	printf("滋賀最低賃金時間額(円)\n");   break;
    case 937:	printf("京都最低賃金時間額(円)\n");   break;
    }
}

時給計算に255円しか表現できないunsigned char を使用するのは避けましょう。


switch(unsigned short型)も避ける

//月収計算には 六万五千五百三十五円 しか表現できない
//unsigned short を避ける
typedef unsigned short U2 ;
void    f3(U2 x)
{
    switch(x){
  case USHRT_MAX: printf("65535\n");      break;
  case 1370000:	printf("19歳以下\n");   break;
  case 2670000:	printf("20〜24歳\n");   break;
  case 3700000:	printf("25〜29歳\n");   break;
  case 4100000:	printf("30〜34歳\n");   break;
  case 4480000:	printf("35〜39歳\n");   break;
    }
}

月収計算に六万五千五百三十五円 しか表現できない unsigned short を使用するのは避けましょう。


■switch(enum型)を使おう

//生涯年収計算は 普通の人は int 型で計算できます
typedef signed int S4 ;
void    f4(S4 x)
{
    switch(x){
    case INT_MIN:printf("マイナス二十一億四千七百四十八万三千六百四十八\n");   break;
    case INT_MAX:printf("二十一億四千七百四十八万三千六百四十七\n");   break;
  case UINT_MAX:printf("四十二億九千四百九十六万七千二百九十五\n");   break;
    }
}

32bitCPU対応のコンパイラならば
signed int型で21億円以上、
unsigned int型で42億円以上表現可能です。

switch(式)の式にはchar/shortの狭い型を避けint型、
できればenum型を使いましょう。

参考:

INT02-C. 整数変換のルールを理解する

https://www.jpcert.or.jp/sc-rules/c-int02-c.html