Bonjour,
je souhaiterais solliciter votre aide car je n'arrive pas du tout à comprendre l'expansion de cette macro pas à pas.

Je connais le résultat : ça produit le 3ème code entre parenthèses si le 1er code est vide, sinon ça produit le 2nd.
Cependant je n'arrive pas à comprendre à partir de quel moment on "bifurque" en fonction de si c'est vide ou pas.

Est-ce qu'il y a des outils permettant de connaître pas à pas l'expansion d'une macro lorsqu'on est dans ce genre de cas afin de mieux la comprendre ?

J'ai beau relire les commentaires ça ne m'aide pas bien évidemment...
De manière plus générale je souhaiterais ré-utiliser ce code dans une autre macro de telle sorte qu'elle ne vérifie QUE si c'est vide ou pas, et non qu'elle inclue une production de code conditionnelle.

Je ne sais pas si j'ai été très clair mais en tous les cas merci d'avance pour votre aide !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
#include <stdio.h>
 
#define _IF_VALUE__SECOND(_a, _b, ...)		_b
// _IF_VALUE__SECOND_2() does the same as _IF_VALUE__SECOND() after an additional round of parameter expansion.
#define _IF_VALUE__SECOND_2(_a, _b, ...)	_IF_VALUE__SECOND(_a, _b, __VA_ARGS__)
// _IF_VALUE__CHECK__IF_VALUE__IS_EMPTY() is used by _IF_VALUE__CHECK to test whether the argument is _IF_VALUE__IS_EMPTY and return _IF_VALUE__IS_EMPTY if so.
#define _IF_VALUE__CHECK__IF_VALUE__IS_EMPTY()	~, _IF_VALUE__IS_EMPTY
// _IF_VALUE__CHECK() produces _IF_VALUE__IS_EMPTY if _first is _IF_VALUE__IS_EMPTY and _IF_VALUE__NOT_EMPTY otherwise.
#define _IF_VALUE__CHECK(_first, ...)		_IF_VALUE__SECOND_2(_IF_VALUE__CHECK_ ## _first (), _IF_VALUE__NOT_EMPTY, ~)
// _IF_VALUE__CHECK_2() does the same as _IF_VALUE__CHECK() after an additional round of parameter expansion.
#define _IF_VALUE__CHECK_2(_first, ...)		_IF_VALUE__CHECK(_first, __VA_ARGS__)
// _IF_VALUE__IS_EMPTY takes 2 groups of parentheses and returns the unwrapped value of the first group.
#define _IF_VALUE__IS_EMPTY(...)		_IF_VALUE__IS_EMPTY_1
#define _IF_VALUE__IS_EMPTY_1(...)		__VA_ARGS__
// _IF_VALUE__NOT_EMPTY takes 2 groups of parentheses and returns the unwrapped value of the second group.
#define _IF_VALUE__NOT_EMPTY(...)		__VA_ARGS__ _IF_VALUE__NOT_EMPTY_1
#define _IF_VALUE__NOT_EMPTY_1(...)		/* nothing */
// IF_VALUE() produces _IF_VALUE__IS_EMPTY if _maybe_empty is empty and _IF_VALUE__NOT_EMPTY otherwise.
#define IF_VALUE(_maybe_empty)	_IF_VALUE__CHECK_2(_IF_VALUE__CHECK _maybe_empty (_IF_VALUE__IS_EMPTY, ~), ~)
 
int main()
{
    int a = IF_VALUE()(2)(3);
    printf("%d", a);
 
    return 0;
}