Question MSVC ne développe pas correctement __VA_ARGS__


Considérez ce code:

#define F(x, ...) X = x and VA_ARGS = __VA_ARGS__
#define G(...) F(__VA_ARGS__)
F(1, 2, 3)
G(1, 2, 3)

Le résultat attendu est X = 1 and VA_ARGS = 2, 3 pour les deux macros, et c'est ce que j'obtiens avec GCC, cependant, MSVC étend ceci comme:

X = 1 and VA_ARGS = 2, 3
X = 1, 2, 3 and VA_ARGS =

C'est, __VA_ARGS__ est développé en un seul argument, au lieu d'être divisé en plusieurs.

Un moyen de contourner cela?


37
2018-02-27 16:59


origine


Réponses:


Le préprocesseur de MSVC semble se comporter différemment de la norme spécification.
Probablement la solution de contournement suivante aidera:

#define EXPAND( x ) x
#define F(x, ...) X = x and VA_ARGS = __VA_ARGS__
#define G(...) EXPAND( F(__VA_ARGS__) )

39
2018-02-27 17:24



Je posté le problème de support Microsoft suivant:

Le programme suivant donne une erreur de compilation car le précompilateur   se développe __VA_ARGS__ incorrectement:

#include <stdio.h>

#define A2(a1, a2) ((a1)+(a2))

#define A_VA(...) A2(__VA_ARGS__)

int main(int argc, char *argv[])
{
    printf("%d\n", A_VA(1, 2));
    return 0;
}

Le préprocesseur étend le printf pour:       printf ("% d \ n", ((1, 2) + ()));

au lieu de       printf ("% d \ n", ((1) + (2)));

J'ai reçu la réponse insatisfaisante suivante d'un développeur de l'équipe de compilation Microsoft:

Salut: le compilateur Visual C ++ se comporte correctement dans ce cas. Si vous combinez la règle selon laquelle les jetons qui correspondent aux "..." à l'invocation initiale de la macro sont combinés pour former une seule entité (16.3 / p12) avec la règle que les sous-macros sont développées avant le remplacement des arguments (16.3.1 / p1) ) dans ce cas, le compilateur estime que A2 est appelé avec un seul argument: d'où le message d'erreur.


16
2017-09-18 06:11



Quelle version de MSVC utilisez-vous? Vous aurez besoin de Visual C ++ 2010.

__VA_ARGS__  a été introduit pour la première fois par C99. MSVC n'a jamais tenté de prendre en charge C99, le support n'a donc pas été ajouté.

Maintenant, cependant __VA_ARGS__ est inclus dans le nouveau standard C ++, C ++ 2011 (précédemment appelé C ++ 0x), que Microsoft envisage apparemment de prendre en charge, il a donc été pris en charge dans les versions récentes de MSVC.

BTW, vous devrez utiliser un .cpp suffixe à votre fichier source pour obtenir ce support. MSVC n'a pas mis à jour son interface C depuis longtemps.


1
2017-09-18 06:28