ホームページ >バックエンド開発 >C++ >MSVC で可変個引数マクロ展開を実現するにはどうすればよいですか?

MSVC で可変個引数マクロ展開を実現するにはどうすればよいですか?

DDD
DDDオリジナル
2024-11-08 14:47:02354ブラウズ

How to Achieve Variadic Macro Expansion in MSVC  ?

MSVC 可変個引数マクロ拡張: 基本と回避策

C プログラミングの領域では、マクロ拡張は、マクロを操作するための強力なツールとなり得ます。そしてオンザフライでコードを生成します。ただし、すべてのコンパイラが可変個の引数を許可する可変個引数マクロを同じ方法で処理できるわけではありません。特に、Microsoft の Visual C (MSVC) コンパイラは、このようなマクロに関しては独特の動作をします。

問題: 意図しない引数の連結

次のように定義された可変長引数マクロについて考えてみましょう。 GCC では次のようになります:

<code class="c++">#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1)</code>

このマクロは、渡される引数の数をカウントすることを目的としています。ただし、GCC で展開すると、各引数が個別に正しく処理され、必要な数が得られます。ただし、 MSVC では、すべての引数が 1 つの引数に連結されます。

回避策: ネストされたマクロとオーバーロード

MSVC で可変個引数マクロ展開を実現するには、以下を使用できます。これは、マクロのネストとオーバーロードを伴う手法です。次のコードは、このアプローチを示しています。

<code class="c++">#define GLUE(x, y) x y

#define RETURN_ARG_COUNT(_1_, _2_, _3_, _4_, _5_, count, ...) count
#define EXPAND_ARGS(args) RETURN_ARG_COUNT args

#define COUNT_ARGS_MAX5(...) EXPAND_ARGS((__VA_ARGS__, 5, 4, 3, 2, 1, 0))

#define OVERLOAD_MACRO2(name, count) name##count
#define OVERLOAD_MACRO1(name, count) OVERLOAD_MACRO2(name, count)
#define OVERLOAD_MACRO(name, count) OVERLOAD_MACRO1(name, count)

#define CALL_OVERLOAD(name, ...) GLUE(OVERLOAD_MACRO(name, COUNT_ARGS_MAX5(__VA_ARGS__)), (__VA_ARGS__))</code>

使用例:

この回避策を使用すると、コンパイラ間で一貫して動作する可変個引数マクロを定義できます。たとえば、次のエラー レポート マクロ:

<code class="c++">#define ERROR(...) CALL_OVERLOAD(ERROR, __VA_ARGS__)</code>

は、可変数の引数でエラーを出力するために使用できます:

<code class="c++">ERROR("Error: %s", errorMessage);  // single argument
ERROR("Error: %s", errorMessage, "Additional details");  // two arguments</code>

Key Insights:

  • MSVC は、GCC や他のコンパイラとは異なる方法で可変個引数マクロ展開を処理します。
  • 入れ子になったマクロとオーバーロードを使用して、MSVC の制限を回避できます。
  • この手法により、次のことが可能になります。 GCC と MSVC の両方で適切に展開される可変個引数マクロの移植可能な作成用。

以上がMSVC で可変個引数マクロ展開を実現するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。