7
int main(void)
{
    #if 0
    something"
    #endif
    return 0;
}

missing terminating " character上記の単純なプログラムは、gccで警告を生成します。これは奇妙に思えます。これは、コンパイラがコード ブロックとの間のコード ブロックを許可し、#if 0ここのendifように無効なステートメントがあることを意味するためですが、ペアにならない二重引用符は許可しないためです。と を使用しても同じことが起こります。something"#ifdef#ifndef

実際のコメントはここで問題ありません:

int main(void)
{
    /*
    something"
    */
    return 0;
}

なんで?一重引用符'も同様に動作しますが、特別に扱っている他のトークンはありますか?

4

4 に答える 4

9

comp.Lang.c FAQ、11.19を参照してください。

ANSI C では、「オフになっている」#if、#ifdef、または #ifndef 内のテキストは、引き続き「有効な前処理トークン」で構成されている必要があります。つまり、文字 " と ' は、実際の C コードと同じようにペアにする必要があり、ペアは行の境界を越えてはなりません。

于 2013-06-22T04:17:49.857 に答える
2

コンパイルは、実行可能なバイナリを生成する前に、多くのサイクルを経る必要があります。

あなたはまだコンパイラにいません。プリプロセッサがこのエラーにフラグを立てています。これは C 言語の構文をチェックしませんが、引用符や中括弧の欠落などはプリプロセッサ エラーです。

このプリプロセッサ パスの後、コードは C コンパイラに送られ、予想されるエラーが検出されます...

于 2013-06-22T04:15:52.860 に答える
1

プリプロセッサはトークン レベルで動作し、文字列リテラルは 1 つのトークンと見なされます。プリプロセッサは、無効なトークンがあることを警告しています。

C99 標準によると、前処理トークンは次のいずれかです。

  • ヘッダー名
  • 識別子
  • pp 番号
  • 文字定数
  • 文字列リテラル
  • 句読点
  • 上記のいずれにもなり得ない各非空白文字

規格には次のようにも書かれています。

' または " 文字が最後のカテゴリに一致する場合、動作は未定義です。

上記の「ステートメント」のようなものは C コンパイラには無効ですが、これは有効なトークンであり、プリプロセッサはコンパイラに到達する前にこのトークンを削除します。

于 2013-06-22T04:15:43.043 に答える
0

ケビンの答えのほかに、GCCの非互換性は次のように述べています。

GCC は、失敗した前処理条件内の未終了の文字定数について不平を言います。一部のプログラムには、失敗することが保証されている条件で囲まれた英語のコメントがあります。これらのコメントにアポストロフィが含まれている場合、GCC はおそらくエラーを報告します。たとえば、次のコードはエラーを生成します。

#if 0
You can't expect this to work.
#endif

このような問題の最善の解決策は、テキストを で区切られた実際の C コメントに入れること/*...*/です。

于 2014-06-15T14:42:18.080 に答える