2016-03-22 7 views
1

Ich arbeite an einem Projekt, und ich muss ein rekursives Makro (hier TEST_COLUMN) simulieren. Aber es scheitert an Visual 2013. Auf gcc funktioniert es richtig, aber mit visuellen, habe ich einen Fehler. Also, um dieses Makro zu debuggen, verwende ich static_assert (vielleicht gibt es einen besseren Weg). Jedes Mal, in den Makros TEST_COLUMN_X (name, ...) enthält der Wert von name ALLE Parameter und nicht nur den ersten.Visual Studio-Makro __VA_ARGS__ nicht korrekt entpackt

Wenn jemand eine Idee haben, das zu beheben. Hier ist der minimale Code benötigt, um es zu reproduzieren:

#define STR_HELPER(x) #x 
#define STR(x) STR_HELPER(x) //transform x to char 

#define EXPAND(x) x 
#define NUM_ARGS_HELPER(X,X64,X63,X62,X61,X60,X59,X58,X57,X56,X55,X54,X53,X52,X51,X50,X49,X48,X47,X46,X45,X44,X43,X42,X41,X40,X39,X38,X37,X36,X35,X34,X33,X32,X31,X30,X29,X28,X27,X26,X25,X24,X23,X22,X21,X20,X19,X18,X17,X16,X15,X14,X13,X12,X11,X10,X9,X8,X7,X6,X5,X4,X3,X2,X1,N,...) N 
//count to number of argument containing 
#define NUM_ARGS(...) EXPAND(NUM_ARGS_HELPER(0, __VA_ARGS__ ,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)) in __VA_ARGS__ 

//define each level of the macro 
#define TEST_COLUMN_0   ; 
#define TEST_COLUMN_1(name)  static_assert(false,"TEST_COLUMN_1 " STR(name)); 
#define TEST_COLUMN_2(name,...) static_assert(false,"TEST_COLUMN_2 " STR(name)); //TEST_COLUMN_1(__VA_ARGS__) 
#define TEST_COLUMN_3(name,...) static_assert(false,"TEST_COLUMN_3 " STR(name)); //TEST_COLUMN_2(__VA_ARGS__) 
#define TEST_COLUMN_4(name,...) static_assert(false,"TEST_COLUMN_4 " STR(name)); TEST_COLUMN_3(__VA_ARGS__) 

//tricks to call the correct macro (TEST_COLUMN_X) 
#define TEST_COLUMN_N1(N,...) TEST_COLUMN_##N(__VA_ARGS__) 
#define TEST_COLUMN(N,...) TEST_COLUMN_N1(N,__VA_ARGS__) 

//recursive macro 
#define TEST_STATIC_COLUMN(...) TEST_COLUMN(NUM_ARGS(__VA_ARGS__), __VA_ARGS__) 

int main(int argc, char* argv[]) 
{ 
    TEST_STATIC_COLUMN(a, b, c); 
    return 0; 
} 

Ausgang:

main.cpp(21): error C2338: TEST_COLUMN_3 a, b, c 

aber es

main.cpp(21): error C2338: TEST_COLUMN_3 a 

du die Online-Compiler http://webcompiler.cloudapp.net/

+0

Der Präprozessor ist dialektvoll, um es so zu sagen. Alle Implementierungen unterscheiden sich auf subtile Weise. Ich denke, wenn ich mit Makros alles andere als trivial machen würde, außer dem üblichen "apply", würde ich die Boost-Präprozessor-Bibliothek verwenden, die die Unterschiede abstrahiert. –

Antwort

0
verwenden, können testen sollten

Ich weiß nicht warum, aber ein paar Aufruf zu EXPAND lösen t sein Problem:

#define TEST_COLUMN_2(name,...) static_assert(false,"TEST_COLUMN_2 " STR(name)); EXPAND(TEST_COLUMN_1(__VA_ARGS__)) 
#define TEST_COLUMN_3(name,...) static_assert(false,"TEST_COLUMN_3 " STR(name)); EXPAND(TEST_COLUMN_2(__VA_ARGS__)) 
#define TEST_COLUMN_4(name,...) static_assert(false,"TEST_COLUMN_4 " STR(name)); EXPAND(TEST_COLUMN_3(__VA_ARGS__)) 
#define TEST_COLUMN_N1(N,...) EXPAND(TEST_COLUMN_##N(__VA_ARGS__)) 
Verwandte Themen