web-dev-qa-db-ja.com

Variadicマクロは非標準ですか?

デバッグビルドでは、警告とエラーをより適切にフォーマットし、追跡と修正が少し簡単になるため、通常はClangを使用します。

しかし最近、可変引数を持つマクロを追加した後、Clangは次のように(ダミープロジェクトから)教えてくれました。

_main.cpp:5:20: warning: named variadic macros are a GNU extension [-Wvariadic-macros]
#define stuff3(args...)  stuff_i(args)
_

macroname(args...)は、Visualstudio、Sunstudio、そしてもちろんGCCを含む幅広いコンパイラで問題なくコンパイルできることを知っています。しかし、clangが正しいことを確認するためだけに、可変引数を拡張する他の2つの方法を試しました。

番号1:

_#define stuff1(...)  stuff_i(...)
_

2番:

_#define stuff2(...)  stuff_i(__VA_ARGS__)
_

両方で私はこのメッセージを受け取ります:

_main.cpp:3:16: warning: variadic macros were introduced in C99 [-Wvariadic-macros]
_

... Variadicマクロが実際にC++の標準の一部であるかどうか(そしてもちろん、プリプロセッサは独立して解釈されることを知っています)

33
user350814

引用 Wikipedia

可変引数マクロは、1999年にC言語標準のISO/IEC 9899:1999(C99)リビジョンで導入され、2011年にISO/IEC 14882:2011(C++ 11)リビジョンでC++言語標準で導入されました。

したがって、これはC99およびC++ 11以降の標準ですが、C++ 03ではGNU拡張機能です。

39
Thomas

C++ 11以降、可変個のマクロは標準C++に含まれるようになりました。 C++ 11標準のセクション16.3は、C99(質問の2番目の形式)の可変個のマクロと互換性があるように可変個のマクロを指定します。

次に、C++での標準準拠の可変長マクロ定義の例を示します。

#define foo(x, y, ...)    bar(x, y, __VA_ARGS__)
28
Dan Moulding

あなたの例の「番号2」の形式では、それらはC99の標準であり、一般にC++コンパイラのプリプロセッサはCとC++のコンパイルで同じです。

それらは、C99コンプライアンスに対する他の頑固な抵抗にもかかわらず、Microsoft VC++もサポートされています。したがって、それとGCCの間には、それらの使用を避けるいくつかの理由があります。私が使用するほとんどの組み込みシステムコンパイラでも、サポートされています。

ただし、「ナンバー1」の形式はGCC固有のものであり、非推奨であることは間違いありません。

4
Clifford

標準は16.3マクロ置換で述べています:

識別子_ _ VA_ARGS _ _は、パラメーターに省略記号表記を使用する関数のようなマクロの置換リストでのみ発生します。

0
Sebastian Mach