2011-01-24 19 views
29

Per i debugbuild, di solito uso Clang, in quanto formatta meglio avvisi e errori, e rende un po 'più facile rintracciarli e correggerli.Le macro Variadic non sono standard?

Ma di recente dopo l'aggiunta di una macro con argomenti variadic, Clang mi ha detto quanto segue (da un progetto fittizio):

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

so che macroname(args...) compila bene in una vasta gamma di compilatori, tra cui VisualStudio, Studio Sole e, naturalmente, GCC. Ma solo per assicurarsi che clang ha ragione, ho provato altri due modi di espandere gli argomenti variadic:

Numero 1:

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

Numero 2:

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

su entrambi ricevo questo messaggio:

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

... il che mi fa chiedere se le macro variadic sono in realtà parte dello standard di C++ (una e naturalmente so che il preprocessore è interpretato in modo indipendente)?

+1

C99 e C++ 0x supportano ufficialmente la versione 2. C++ 03 non supporta le macro variadic.La versione 1 è un'estensione specifica del GCC – sellibitze

+0

(come il tuo nome) quando compili con GCC c'è l'opzione '-pedantic' che dovrebbe riportare le estensioni utilizzate. Come Array a lunghezza variabile o Macro variabile, ad esempio. In GCC sono inclusi semplicemente perché poiché fanno parte di C99, la logica è già implementata, quindi deve essere sembrata una buona idea lasciare che il C++ folk ne tragga beneficio :) –

+0

@Matthieu M: Sì, in effetti ho anche pensato che questa funzione sarebbe parte di C++, dato che è già parte del C99 ... interessantemente, gcc non dice che i macro variadic nominati sono in effetti delle estensioni GNU, ma invece dice solo che non fanno parte dello standard: 'warning: ISO C non consente macro denominate variadic' –

risposta

36

Citazione Wikipedia:

macro Variable-argomenti sono stati introdotti nel 1999 nella norma ISO/IEC 9899: 1999 (C99) revisione della norma linguaggio C, e nel 2011 in ISO/IEC 14882: 2011 (C++ 11) revisione dello standard di linguaggio C++.

Quindi è standard da C99 e C++ 11 in poi, ma un'estensione GNU in C++ 03.

4

Nella forma dell'esempio "Numero 2", sono standard in C99 e generalmente il preprocessore del compilatore C++ è lo stesso per la compilazione C e C++.

Sono supportati anche Microsoft VC++ nonostante la sua resistenza altrimenti ostinata alla conformità C99. Quindi tra questo e GCC ci sono alcuni motivi per evitare di usarli. Anche sulla maggior parte dei compilatori di sistemi incorporati che utilizzo sono supportati.

Evitare il modulo "Numero 1", tuttavia, che è fermamente specifico del GCC, e senza dubbio deprecato.

0

standard dice nel 16.3 Macro sostituzione:

L'identificatore _ _ VA_ARGS _ _ deve avvenire solo nella sostituzione-list di una funzione macro-like che utilizza la notazione puntini di sospensione nei parametri.

26

A partire da C++ 11, le macro variadic sono ora incluse in C++ standard. La sezione 16.3 dello standard C++ 11 specifica macro variadiche tali da essere compatibili con macro variadiche da C99 (la seconda forma nella domanda).

Ecco un esempio di una definizione di macro variadic conforme agli standard in C++:

#define foo(x, y, ...) bar(x, y, __VA_ARGS__) 
+1

È conforme allo standard, ma soffre anche del bug della virgola, se si deve credere a Wikipedia. –

+0

@AlexeiAverchenko: ho visto nella documentazione di gcc che la virgola verrà rimossa se non viene inserito nulla nel ... tuttavia oggi porto il codice a clang e sto ricevendo l'errore 'expected expression' e non ho ancora finito comprenderlo. può essere correlato –

Problemi correlati