• ベストアンサー

ifdefとenum

enum { INDEX_A = 0, INDEX_B, INDEX_C, INDEX_END }; #ifndef INDEX_END #define INDEX_END 10 #endif enum{}文で定義した名前は#ifndef,#ifdef文の対象外でしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

列挙体の定義は、#ifndefや#defineなどの前処理指令を解決した後で意味解析が行われます。ですから、#ifndef指令が解決される段階では列挙定数INDEX_ENDは特定の意味を持つ存在としてはコンパイラに認識されません。結果として、INDEX_ENDはマクロとして定義されていない識別子ですので、#define INDEX_END 10が有効になります。 ちなみに、#if INDEX_ENDとした場合、INDEX_ENDは定義されていないマクロ名ですので0として評価されることになります。

参考URL:
http://portable-c.jugem.jp/?eid=7
matyrcry
質問者

お礼

あーっ!まさにこういう話です。 ありがとうございます。 すっきりしました。

その他の回答 (2)

  • MrBan
  • ベストアンサー率53% (331/615)
回答No.3

暗黙の規則というか言語仕様書に書かれているかと。 C++ならISO/IEC14882:2003 16.1 Conditional inclusionあたり。 [... if the identifier is currently defined as a macro name ...] 「macro nameとして定義されてるか否か」が条件です。 # C言語は調べてませんがたしか一緒だったはず。

matyrcry
質問者

お礼

ありがとうございます。 マクロ名ということは、列挙ではダメなんですね。 ISOの仕様書は知らなかったので、探して読んでみます。

  • asuncion
  • ベストアンサー率33% (2127/6290)
回答No.1

投稿を元にして、ちょっとしたサンプルを作ってみました。 実行結果に基づいて判断してみてください。 #include <stdio.h> enum {   INDEX_A = 0,   INDEX_B,   INDEX_C,   INDEX_END }; #ifndef INDEX_END #define INDEX_END 10 #endif int main(void) {   printf("%d %d %d %d\n", INDEX_A, INDEX_B, INDEX_C, INDEX_END);   return 0; } (注)インデントのため、全角空白を使っています。

matyrcry
質問者

お礼

回答ありがとうございます。 残念ながら、実行結果が正しいのかどうかを疑っているところです ので、そこからは判断できません。 具体的には、リアルタイムOSのカーネルソースをコンパイルしよう として、生成情報の中のリソース使用数のデータ名としてenumで定 義した名前を与えてみたところ、#ifdefの対象外のため、ユーザ未 定義として初期値で上書きされてしまったが、それが基本仕様なの か不具合の類なのか判断がつかないという状況です。 コンパイラのマニュアルの言語仕様としては記述がなかったので、 暗黙でそういう規則があるのかどうか知りたいです。

関連するQ&A