プリプロセッサを使用して行にコメントを付けたい:
#define open /##*
#define close */
main()
{
open commented line close
}
$gcc -E filename.c
私が期待したとき
/* commented line */
しかし、私は得ました
/ * commented line */
コンパイラがエラーを表示するように
なぜそれが不要なスペースを与えているのですか?
プリプロセッサを使用して行にコメントを付けたい:
#define open /##*
#define close */
main()
{
open commented line close
}
$gcc -E filename.c
私が期待したとき
/* commented line */
しかし、私は得ました
/ * commented line */
コンパイラがエラーを表示するように
なぜそれが不要なスペースを与えているのですか?
GNU Cプリプロセッサのドキュメントから:
ただし、一緒に有効なトークンを形成しない2つのトークンを一緒に貼り付けることはできません。たとえば、xと+をどちらの順序でも連結することはできません。試行すると、プリプロセッサは警告を発行し、2つのトークンを発行します。トークンの間に空白を入れるかどうかは未定義です。複雑なマクロで「##」の不要な使用法を見つけるのはよくあることです。この警告が表示された場合は、単に「##」を削除できる可能性があります。
この場合、「*」と「/」は有効なCまたはC++トークンを形成しません。したがって、それらはそれらの間にスペースを置いて放出されます。
(余談ですが、Cプリプロセッサの出力に「コメント」を挿入できたとしても、Cコンパイルエラーが発生する可能性があります。コメントはありません。)
エラーは、/*
が有効なトークンではないためです。
CPPドキュメントから説明されているように:
一緒に有効なトークンを形成しない2つのトークンを一緒に貼り付けることはできません。たとえば、どちらの順序でも連結
x
することはできません。+
/##+
またはなど、他のナンセンスなものを貼り付けることでエラーが発生する可能性があります+##-
。
スペースについては、コメントの作成を避け、残りを台無しにするために意図的に挿入されています。GCCソースコードから:
/* Avoid comment headers, since they are still processed in stage 3.
It is simpler to insert a space here, rather than modifying the
lexer to ignore comments in some circumstances. Simply returning
false doesn't work, since we want to clear the PASTE_LEFT flag. */
if ((*plhs)->type == CPP_DIV && rhs->type != CPP_EQ)
*end++ = ' ';
プリプロセッサは、Cコンパイラが理解できる形式でコードを実行および生成します。コードは1回しか処理されないため、を使用してを生成できたとしても、有効なCコード(前処理命令)ではないため、コンパイラはを認識してエラーを出します。/*
#define
/*
これはあまり良いことではないようです。
コメントは、プリプロセッサが実行される前(および実行前のみ)にスペースに置き換えられるためです。文字を貼り合わせてプリプロセッサを使用する/
と、2つの演算子だけが表示されます。編集:このような悪用は、技術的には未定義の動作を持つ単一のトークンとして作成されます。一緒に貼り付けることもできますが、貼り付けることはできません。*
/*
##
/*
> ## >
< %:%: :
作成できるトークンについてはC99の§6.4.6を、カテネーションプロセスについては6.10.3.3を参照してください。
プリプロセッサを使用してコードにコメントを付ける場合は、
#if 0
...
#endif