6

次のコードがコンパイルされるのはなぜですか?

#ifdef C++11
// ...
#endif

int main() {}

gcc 4.8.0 では、次の警告が表示されます。

#ifdef ディレクティブの末尾に追加のトークン

標準によると、マクロ名には文字、数字、およびアンダースコア文字のみを含めることができます。

もしかしてこれのせい?

ISO/IEC 14882:2011

16.1 条件付き包含 [cpp.cond]

6 各ディレクティブの条件が順番にチェックされます。false (ゼロ) と評価された場合、それが制御するグループはスキップされます。ディレクティブは、ネストされた条件のレベルを追跡するためにディレクティブを決定する名前によってのみ処理されます。グループ内の他の前処理トークンと同様に、残りのディレクティブの前処理トークンは無視されます。制御条件が true (ゼロ以外) と評価される最初のグループのみが処理されます。どの条件も true と評価されず、#else ディレクティブがある場合、#else によって制御されるグループが処理されます。#else ディレクティブがない場合、#endif までのすべてのグループがスキップされます.151

この引用を正しく理解できません。

4

2 に答える 2

1

A#ifdefは次のように定義されます (§16.1 から取得)

# ifdef      識別子改行

正規表現のような表記では、識別子は次のとおりです: [a-zA-Z_][a-zA-Z_0-9]*(*)

ポイントは、宣言するマクロが NOT であることですC++11。実際にそうですC(このライブの例を参照してください)。この++11部分はプリプロセッサによって無視されます。識別子の後に許可されている唯一の文字 (これはC) は改行ですが、hvd の回答で述べたように、§1.4 から、構文エラーは診断メッセージのみを強制します。ここでは警告です。エラーの代わりにこれが表示される唯一の理由は、そのような名前が使用されていた古いコードと互換性があるためです。

また、引用は、条件が指定される方法ではなく、どのよう#ifdef / #elif / #else / #endifに連携するかを説明しています。

私は標準のコピーを持っていません。この回答にはドラフトn3485を使用しました。

(*)識別子に実装定義の文字を含めることは可能ですが、それはあなたの質問には影響しません。変数、クラス名、マクロなどはすべて同じ識別子規則に従うことに注意してください。

于 2013-04-10T20:46:50.467 に答える