[1744] Cにおける列挙型の扱いについて
投稿者:yuya
2011/10/07 09:35:26
C限定の話で、列挙型についての疑問です。
JIS X3010:2003の6.7.2.2 列挙型指定子(p77~p78)に、
> 制約 列挙定数の値を定義する式は、int型で表現可能な値を持つ整数定数式でなければならない
(中略)
>それぞれの列挙型は、char、符号付き整数型又は符号無し整数型と適合する型とする。型の選択は、処理系定義とする。しかし、その型は列挙型のすべてのメンバの値を表現できなければならない。
とあります。
列挙型が必ずしもint型ではなく上記のような選択の余地を処理系に与えているのは、
例えばメンバの値の範囲がcharで収まるなら、処理系はcharを使って領域を節約してもよい、という意義だと理解してよいのでしょうか?
通常、列挙体のメンバを式中で用いるときには、何も意識せずにint型の定数として
(私は)書いているのですが、このメンバ自体はint型とは限らないわけですよね。
ある列挙型に対して例えば「charと適合する型」が選ばれた場合、そのメンバは
あくまで「(charと適合する)列挙型の列挙定数」であって、
式の中に現れると汎整数拡張されてint型に格上げされる、という理解でよいのでしょうか?
この疑問が生じた直接のきっかけは、(ぱ)さんの「プログラミング言語MIL」の雑誌記事のmini_mvm.cにおいて、
(A)や(B)の箇所でintへのキャストがなされているのを見て、「どんなときにキャストすべきなんだっけ?」と再考したことによります。
相変わらず記事の本筋と関係なくてすみません……。
皆様よろしければご教示ください。
typedef enum {
OP_PUSH_INT,
OP_ADD,
OP_MUL,
OP_PRINT
} OpCode;
int g_bytecode[] = { /* (A) */
(int)OP_PUSH_INT,
10,
(int)OP_PUSH_INT,
2,
(int)OP_PUSH_INT,
4,
(int)OP_MUL,
(int)OP_ADD,
(int)OP_PRINT,
};
int st_stack[STACK_SIZE_MAX];
void mvm_execute(void){
int pc = 0;
int sp = 0; // スタックポインタ
while (pc < sizeof(g_bytecode) / sizeof(*g_bytecode)) {
switch (g_bytecode[pc]) {
case OP_PUSH_INT: // 整数をスタックに積む
st_stack[sp] = (int)g_bytecode[pc+1]; /* (B) */
sp++;
pc += 2;
break;
case OP_ADD: // 加算
/* 以下略 */
}
}
}