La soluzione in questione è questo:
#define EXPAND(x) x
#define F(x, ...) X = x and VA_ARGS = __VA_ARGS__
#define G(...) EXPAND(F(__VA_ARGS__))
L'idea è che, dato uno esistente variadic macro F()
:
#define F(x, ...) X = x and VA_ARGS = __VA_ARGS__
invece di scrivere macro involucro variadic desiderato come, in questo caso, ...
#define G(...) F(__VA_ARGS__)
... si scrive G()
con l'uso della macro EXPAND()
aggiuntiva. La definizione attuale di F()
non è il punto, e in particolare non è rilevante per questo esempio che l'espansione macro non produca codice C valido. Il suo scopo è dimostrare il comportamento del preprocessore rispetto agli argomenti macro. Nello specifico, mostra che sebbene MSVC espanda __VA_ARGS__
in un singolo token in una macro variadic, ciò può essere aggirato forzando una doppia espansione.
Ad esempio, utilizzando la definizione soluzione, il preprocessore prima espande ...
G(1, 2, 3)
... al ...
EXPAND(F(1, 2, 3))
... dove il 1, 2, 3
viene considerato come gettone singolo. Tale tokenizzazione non ha più importanza quando il preprocessore esegue la copia per sostituzioni aggiuntive, tuttavia: vede lo 1
, 2
, 3
come argomenti separati alla macro F()
e lo espande come desiderato per produrre l'argomento della macro EXPAND()
, che lo sostituisce con se stesso.
Se ritieni strano che funzioni come previsto, ma la versione senza EXPAND()
non funziona (in MSVC), hai ragione.
fonte
2015-09-04 14:06:36
Penso che il post collegato non sia corretto. Penso che la soluzione giusta sia 'G (...) F (EXPAND (__ VA_ARGS__))' – LPs
@LPs, l'ho pensato anch'io, ma provalo. –
@JohnBollinger Sono troppo Linux dentro per mettere le mani su MSVC :). Seriamente, non ho MSVC per testarlo. Lascia che OP lo provi – LPs