Cプリプロセッサをいじっていたところ、非常に単純に見えたものが失敗しました。
#define STR_START "
#define STR_END "
int puts(const char *);
int main() {
puts(STR_START hello world STR_END);
}
gcc でコンパイルすると (注意: clang で同様のエラーが発生します)、次のエラーで失敗します。
$ gcc test.c test.c:1:19: 警告: 終端 " 文字がありません test.c:2:17: 警告: 終端 " 文字がありません test.c: 関数 'main' 内: test.c:7: エラー: 終端 " 文字がありません test.c:7: エラー: 'hello' が宣言されていません (この関数で最初に使用) test.c:7: エラー: (宣言されていない識別子はそれぞれ一度だけ報告されます test.c:7: エラー: 各関数に表示されます。) test.c:7: エラー: 'world' の前に ')' が必要です test.c:7: エラー: 終端 " 文字がありません
これは私を混乱させたので、プリプロセッサを介して実行しました:
$ gcc -E test.c #1 「test.c」 #1「」 #1「」 #1 「test.c」 test.c:1:19: 警告: 終端 " 文字がありません test.c:2:17: 警告: 終端 " 文字がありません int puts(const char *); int main() { puts("こんにちは世界"); }
警告にもかかわらず、これは完全に有効なコード (太字のテキスト) を生成します!
Cのマクロが単なるテキストの置換である場合、最初の例が失敗するのはなぜですか? これはコンパイラのバグですか? そうでない場合、標準のどこにこのシナリオに関する情報がありますか?
注:最初のスニペットをコンパイルする方法を探しているわけではありません。このシナリオが失敗する理由に関する情報を探しているだけです。