2016-07-05 3 views
1

定義済みの用語リストに対して繰り返しを実行するマクロを作成しようとしており、それぞれ別のマクロを呼び出す可能性があります。ここで私は持っているものです:バリデーションマクロの引数の数が無効

#define ITERATE_OVER_TERMS(MACRO, ...) \ 
MACRO(Term1, __VA_ARGS__) \ 
MACRO(Term2, __VA_ARGS__) \ 
MACRO(Term3, __VA_ARGS__) \ 
... and so on 

私は、Visual Studio 2015でそれを使用しようとしていたときしかし、私はエラーBODYとして渡されたマクロの名前である

warning C4003: not enough actual parameters for macro 'BODY' 

を取得MACRO引数。技術的には警告だが、それは何かが拡大に間違っていることを示しています。エラーを絞り込むための試みにおいて

は、私は次のように私の例を削減:上記のように、私はそれが正常にコンパイルして出力を生成すると予想しながら、それは私にエラーを与える

#include <iostream> 

#define ITERATE(MACRO, ...) \ 
MACRO(1, __VA_ARGS__) MACRO(2, __VA_ARGS__) 

#define BODY(IterationArg, Arg1, Arg2) \ 
std::cout << IterationArg << Arg1 << Arg2 << std::endl; 

int main() { 
    ITERATE(BODY, 8, 9) 
    return 0; 
} 

189 
289 

g ++ではコンパイルされているようですが、Visual Studioではコンパイルできません。 私は何が欠けていますか?これが動作するためのいくつかの回避策はありますか?

+0

Visual Studio 2015はまだC99プリプロセッサの一部をサポートしています。ソース:https://msdn.microsoft.com/en-us/library/hh567368.aspx – KABoissonneault

+0

@KABoissonneault彼らは長い間、可変的なマクロをサポートしているようです(https://msdn.microsoft.com/en-us/library)。 /ms177415.aspx)既にVS2005のバージョンがあります。 – CygnusX1

+0

これらは可変的なマクロをサポートしていますが、マクロの引数として渡されたマクロは見たことがありません。 Visual Studioはおそらくあなたが 'main'本体の中で' BODY'を評価することを期待しています。 – KABoissonneault

答えて

2

問題はVisual Studioが__VA_ARGS__を後続のマクロに渡した後で展開した後に展開することにあります。私たちにその内容を示す、

#include <iostream> 

#define ITERATE(MACRO, ...) \ 
MACRO(1, __VA_ARGS__) MACRO(2, __VA_ARGS__) 

#define BODY(IterationArg, Arg1, Arg2) \ 
std::cout << #Arg1 << std::endl; 

int main() { 
    ITERATE(BODY, 8, 9) 
    return 0; 
} 

が引数#Arg1が文字列化された:コード内で簡単な変更を検討し、あなたのケースでは Why does this variadic argument count macro fail with VC++?

- これは、ここでは例のためだけでなく、過去に問題を起こしています出力:

8, 9 
8, 9 

期待したとおりではありませんか?

ソリューションは、リンクされた問題と同じです:ダミーEXPANDマクロを通じて展開を強制:

#define EXPAND(x) x 

#define ITERATE(MACRO, ...) \ 
EXPAND(MACRO(1, __VA_ARGS__)) EXPAND(MACRO(2, __VA_ARGS__)) 

これはあなたのVSとgccの両方で望ましい結果を提供します。