2016-08-16 6 views
1

Проблема довольно проста: я просто не могу передать второе расширение макроса, он сообщает об ошибке на Visual Studio 2013 и 2015, но хорошо работает на GCC и Clang.Проблема с расширением препроцессора C++

#include <iostream> 

#define KS_MACRO_TAIL(A, ...) __VA_ARGS__ 
#define KS_MACRO_DELAY(M, ...) M(__VA_ARGS__) 

int main() 
{ 
    int XX = 1; 
    std::cout << KS_MACRO_TAIL (_, XX) << std::endl; 
    std::cout << KS_MACRO_DELAY (KS_MACRO_TAIL, _, XX); 
} 

Visual Studio генерирует следующий эквивалент:

int main() 
{ 
    int XX = 1; 
    std::cout << XX << std::endl; 
    std::cout << ; 
} 

Где std::cout << ; ошибка синтаксиса, но приведенное выше утверждение верно.

+4

Что ошибка сообщается? –

+0

Работает отлично с 'gcc -E' на gcc 5.4.0 (обе строки расширяются до' XX'), поэтому предположительно VS-специфические. Ошибка компилятора будет зависеть от контекста, в котором вы используете макрос, поэтому, пожалуйста, [отредактируйте свой вопрос] (https://stackoverflow.com/posts/38975545/edit), чтобы показать, как используется KS_MACRO_DELAY', и, как сказал @ScottHunter, точно, о чем сообщается ошибка. – cxw

ответ

0

VS2015 не подходит для решения ваших макросов так, как вы этого хотите. Предлагаю воспользоваться обходным решением

#define KS_MACRO_DELAY1(M, X) M(X) 
#define KS_MACRO_DELAY2(M, X1, X2) M(X1, X2) 
#define KS_MACRO_DELAY3(M, X1, X2, X3) M(X1, X2, X3) 
#define KS_MACRO_DELAY4(M, X1, X2, X3, X4) M(X1, X2, X3, X4) 
// etc. 

Или вам следует подумать о решении, которое не предполагает использование макросов вообще.

2

Добавление одного дополнительного определения MACRO между вызовом KS_MACRO_DELAY и KS_MACRO_TAIL:

#define KS_MACRO_TAIL(A, ...) __VA_ARGS__ 
#define KS_MACRO_EVAL(...) __VA_ARGS__ 
#define KS_MACRO_DELAY(X, ...) KS_MACRO_EVAL(X(__VA_ARGS__)) 
+0

Отличное решение. 'KS_MACRO_DELAY (KS_MACRO_TAIL, _, XX);' работает с этим. Вложенные вызовы все еще не компилируются: 'KS_MACRO_DELAY (KS_MACRO_DELAY, KS_MACRO_DELAY, KS_MACRO_TAIL, _, XX);' Почему? – TobiMcNamobi