ti-enxame.com

As macros Variadic são fora do padrão?

Para debugbuilds, eu costumo usar o Clang, pois ele formata melhor os avisos e erros, e torna um pouco mais fácil rastreá-los e corrigi-los.

Mas recentemente, depois de adicionar uma Macro com argumentos variadicos, Clang me disse o seguinte (de um projeto simulado):

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

Eu sei que macroname(args...) compila bem em uma ampla gama de compiladores, incluindo Visualstudio, Sunstudio e, claro, GCC. Mas só para ter certeza de que o clang está certo, eu tentei duas outras maneiras de expandir os argumentos variadicos:

Número 1:

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

Número 2:

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

Em ambos recebo esta mensagem:

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

... O que me faz pensar se as macros Variadic são realmente parte do padrão de C++ (e é claro que eu sei que o pré-processador é interpretado independentemente)?

33
user350814

Citações Wikipedia :

As macros de argumento variável foram introduzidas em 1999 na revisão ISO/IEC 9899: 1999 (C99) do padrão de linguagem C e, em 2011, na revisão ISO/IEC 14882: 2011 (C++ 11) do padrão de linguagem C++.

Portanto, é padrão a partir de C99 e C++ 11 em diante, mas uma extensão GNU em C++ 03.

39
Thomas

A partir do C++ 11, as macros variadic estão agora incluídas no C++ padrão. A seção 16.3 do padrão C++ 11 especifica macros variadic de modo que sejam compatíveis com macros variadic de C99 (a segunda forma na questão).

Aqui está um exemplo de uma definição de macro variadic em conformidade com o padrão em C++:

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

Na forma do seu exemplo "Número 2", eles são padrão em C99 e, geralmente, o pré-processador de um compilador C++ é o mesmo para a compilação C e C++.

Eles também são compatíveis com o Microsoft VC++, apesar de sua resistência teimosa à conformidade com o C99. Então, entre isso e o GCC, há poucas razões para evitar usá-los. Mesmo na maioria dos compiladores de sistemas embarcados eu uso eles são suportados.

No entanto, evite o formulário "Número 1", que é específico do GCC e, sem dúvida, obsoleto.

4
Clifford

Standard diz em 16,3 Substituição de macro :

O identificador _ _ VA_ARGS _ _ deve ocorrer somente na lista de substituição de uma macro de função que usa a notação de reticências Nos parâmetros.

0
Sebastian Mach