Extension de macros variadiques MSVC : les bases et une solution de contournement
Dans le domaine de la programmation C, l'expansion de macros peut être un outil puissant pour manipuler et générer du code à la volée. Cependant, tous les compilateurs ne gèrent pas de la même manière les macros variadiques, qui permettent un nombre variable d’arguments. Le compilateur Visual C (MSVC) de Microsoft, en particulier, a un comportement distinct lorsqu'il s'agit de telles macros.
Le problème : la concaténation involontaire d'arguments
Considérez une macro variadique définie comme suit dans GCC :
<code class="c++">#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1)</code>
Cette macro est destinée à compter le nombre d'arguments qui lui sont passés. Cependant, lorsqu'il est développé dans GCC, il traite correctement chaque argument comme individuellement, nous donnant le nombre souhaité. Dans MSVC, cependant, tous les arguments sont concaténés en un seul argument.
La solution de contournement : macros imbriquées et surcharge
Pour réaliser une expansion de macro variadique dans MSVC, nous pouvons utiliser une technique qui implique l'imbrication de macros et la surcharge. Le code suivant illustre cette approche :
<code class="c++">#define GLUE(x, y) x y #define RETURN_ARG_COUNT(_1_, _2_, _3_, _4_, _5_, count, ...) count #define EXPAND_ARGS(args) RETURN_ARG_COUNT args #define COUNT_ARGS_MAX5(...) EXPAND_ARGS((__VA_ARGS__, 5, 4, 3, 2, 1, 0)) #define OVERLOAD_MACRO2(name, count) name##count #define OVERLOAD_MACRO1(name, count) OVERLOAD_MACRO2(name, count) #define OVERLOAD_MACRO(name, count) OVERLOAD_MACRO1(name, count) #define CALL_OVERLOAD(name, ...) GLUE(OVERLOAD_MACRO(name, COUNT_ARGS_MAX5(__VA_ARGS__)), (__VA_ARGS__))</code>
Exemple d'utilisation :
Avec cette solution de contournement, nous pouvons définir des macros variadiques qui se comportent de manière cohérente entre les compilateurs. Par exemple, la macro de rapport d'erreurs suivante :
<code class="c++">#define ERROR(...) CALL_OVERLOAD(ERROR, __VA_ARGS__)</code>
peut être utilisée pour générer des erreurs avec un nombre variable d'arguments :
<code class="c++">ERROR("Error: %s", errorMessage); // single argument ERROR("Error: %s", errorMessage, "Additional details"); // two arguments</code>
Key Insights :
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!