Reputation: 25
I am currently automating the creation of multiple functions with almost the same content. This is the minimal sample of this project:
#include <stdio.h>
#define _macro_print(m) printf("Value: %x\n", test_##m);
#define _macro_var_def(m) int test_##m = m;
// Repeat macro d n-times
#define BSV_REPEAT(n, d) _BSV_REPEAT_##n(d)
#define _BSV_REPEAT_1(d) _macro_##d(0)
#define _BSV_REPEAT_2(d) _BSV_REPEAT_1(d)_macro_##d(1)
#define _BSV_REPEAT_3(d) _BSV_REPEAT_2(d)_macro_##d(2)
#define _BSV_REPEAT_4(d) _BSV_REPEAT_3(d)_macro_##d(3)
#define NUMBER_OF_TIMES 4
int main() {
BSV_REPEAT(4, var_def)
// NUMBER_OF_TIMES
BSV_REPEAT(4, print)
//BSV_REPEAT(NUMBER_OF_TIMES, print)
return 0;
}
The actual macro behind _macro_print is a lot more complex, so it is not possible to do it at runtime with a for-loop or something similar.
In the real project I use the BSV_REPEAT macro multiple times with different macros but always with the same number of repetitions. Naturally I wanted to create a define for this number so that I can change it easily later on.
When I use the define NUMBER_OF_TIMES CLion reports the following message and the program can not longer be compiled.
My question is now how to solve this problem? Is there a way to force the evaluation of NUMBER_OF_TIMES earlier?
Upvotes: 2
Views: 105
Reputation: 26703
You need to control the expanding order.
To do that introduce a dedicated additional layer of expanding and concatenating:
#define _macro_print(m) printf("Value: %x\n", test_##m);
#define _macro_var_def(m) int test_##m = m;
#define CONCAT(x,y) x##y
// Repeat macro d n-times
#define BSV_REPEAT(n, d) CONCAT(_BSV_REPEAT_,n)(d)
#define _BSV_REPEAT_1(d) CONCAT(_macro_,d)(0)
#define _BSV_REPEAT_2(d) _BSV_REPEAT_1(d)CONCAT(_macro_,d)(1)
#define _BSV_REPEAT_3(d) _BSV_REPEAT_2(d)CONCAT(_macro_,d)(2)
#define _BSV_REPEAT_4(d) _BSV_REPEAT_3(d)CONCAT(_macro_,d)(3)
#define NUMBER_OF_TIMES 4
int main() {
BSV_REPEAT(4, var_def)
NUMBER_OF_TIMES
BSV_REPEAT(4, print)
BSV_REPEAT(NUMBER_OF_TIMES, print)
return 0;
}
Output of above with -E
option:
int main() {
int test_0 = 0;int test_1 = 1;int test_2 = 2;int test_3 = 3;
4
printf("Value: %x\n", test_0);printf("Value: %x\n", test_1);printf("Value: %x\n", test_2);printf("Value: %x\n", test_3);
printf("Value: %x\n", test_0);printf("Value: %x\n", test_1);printf("Value: %x\n", test_2);printf("Value: %x\n", test_3);
return 0;
}
And please shed the habit of using identifiers wich start with "_", they are reserved.
Upvotes: 2