I’m trying to understand usage of macros in C++, particularly invoking macros from within another. The below example prints “`Y4“ as one might expect.
#include <iostream>
#define NUM_ARGS_IMPL(_1, _2, _3, _4, X, ...) X
#define NUM_ARGS(...) NUM_ARGS_IMPL(..., 1, 2, 3, 4)
#define CONCAT_(X,Y) X##Y
#define CONCAT2_(X,Y) CONCAT_(X,Y)
#define S3(X) #X
#define S2(X) S3(X)
#define STRINGIZE(X,...) S2(CONCAT2_(X, NUM_ARGS(__VA_ARGS__)))
#define SUB2(X) (X-1)
#define SUB(X) SUB2(X)
#include <vector>
int main() {
std::cout << STRINGIZE(Y, 1, 3, 4) << "n";
}
I would like to change the output to Y3 and to that end the following did not work
Changing STRINGIZE
to below
#define STRINGIZE(X,...) S2(CONCAT2_(X, SUB(NUM_ARGS(__VA_ARGS__))))
Error
<source>:18:16: error: pasting formed 'Y(', an invalid preprocessing token
std::cout << STRINGIZE(Y, 1, 3, 4) << "n";
^
<source>:14:29: note: expanded from macro 'STRINGIZE'
#define STRINGIZE(X,...) S2(CONCAT2_(X, SUB2(NUM_ARGS(__VA_ARGS__))))
^
<source>:7:23: note: expanded from macro 'CONCAT2_'
#define CONCAT2_(X,Y) CONCAT_(X,Y)
^
<source>:6:23: note: expanded from macro 'CONCAT_'
#define CONCAT_(X,Y) X##Y
^
1 error generated.
Compiler returned: 1
What is the issue here?
Furthermore, even the code with first macro that generates Y4 fails to compile if I just add another parentheses around NUM_ARGS
, why is that the case?
#define STRINGIZE(X,...) S2(CONCAT2_(X, (NUM_ARGS(__VA_ARGS__))))
^
New contributor
user1234234 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
2