13

次のC++コードは、GCC(4.0.4)で意図されたプログラマーとしてコンパイルおよび動作します。

#define FOO(x,y,z) ((x)*(y)*(z))
#define BAR(x) FOO(x,1)
#define BAZ 3,7

int main()
{
    return BAR(BAZ); /* interpreted as return ((3)*(7)*(1)); */
}

ただし、マクロにより、Microsoft Visual C ++Express2010でエラーが発生します。

main.cpp(7):警告C4003:マクロ'FOO'の実際のパラメーターが不足しています
main.cpp(7):エラーC2059:構文エラー:')'

問題は、MicrosoftコンパイラがBARマクロを内部で処理しているときに、BAZマクロをマクロFOOの2つの別個のパラメータとして使用できるパラメータに展開しないことであると思われます。

標準によると、どのコンパイラが状況を正しく処理しますか?

4

1 に答える 1

13

ISO / IEC 14882:2003(C ++ Stardard)の16.3.4によると、マクロ展開は次のように実行されます。

  1. マクロ呼び出しは、マクロの置換リスト(本体)に置き換えられます。各パラメーター名は(#または##の影響を受けない限り)、マクロ呼び出しで指定された対応する引数の完全なマクロ展開に置き換えられます。
  2. 手順1の結果が再スキャンされます。その中にさらにマクロ呼び出しがある場合(検討中のテキストを取得するためにすでに展開されているものを除く)、それらは同じ手順に従って再帰的に展開されます。

指定したコードの一連の手順は次のとおりです。

  1. BAR(BAZ)
  2. FOO(3,7,1)
  3. ((3)*(7)*(1))

したがって、GCCは正しく、VCは正しくありません。しかし、VCが不満を言うエラーは、FOO3つの引数がありBAR、そのうちの2つだけを指定していることです。VCは明らかに、できるだけ早くエラーをキャッチしようとし、少し行き過ぎています。

于 2012-05-21T11:38:08.193 に答える