アプリ版:「スタンプのみでお礼する」機能のリリースについて

enum {
INDEX_A = 0,
INDEX_B,
INDEX_C,
INDEX_END
};

#ifndef INDEX_END
#define INDEX_END 10
#endif

enum{}文で定義した名前は#ifndef,#ifdef文の対象外でしょうか?

A 回答 (3件)

列挙体の定義は、#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
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/04/24 08:06

暗黙の規則というか言語仕様書に書かれているかと。



C++ならISO/IEC14882:2003 16.1 Conditional inclusionあたり。
[... if the identifier is currently defined as a macro name ...]
「macro nameとして定義されてるか否か」が条件です。

# C言語は調べてませんがたしか一緒だったはず。
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/04/24 08:13

投稿を元にして、ちょっとしたサンプルを作ってみました。


実行結果に基づいて判断してみてください。

#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;
}

(注)インデントのため、全角空白を使っています。
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/04/23 16:56

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!