In my code there are multiple structures like structure_1, structure_2, structure_3 etc. I am trying to write a macro which will enable me to select the correct structure (which structure to select is based on another value). I can't reveal the exact code...but its similar to this
#include <stdio.h>
#define concat(X,Y) X##_##Y
#define typename(X){\
if(val==0)\
concat(X,1)\
else\
concat(X,2)\
}
int val;
typedef struct {
int x;
char c;
}structure_1;
typedef struct {
int y;
char c;
}structure_2;
int main() {
val = 0;
typename(structure) abc;
abc.x = 0;
printf("%d\n",abc.x);
}
This doesn't work and is giving issues
24 11 E:\DEV\concat.c [Error] expected expression before 'structure_1'
3 22 E:\DEV\concat.c [Note] in definition of macro 'concat'
24 2 E:\DEV\concat.c [Note] in expansion of macro 'typename'
25 2 E:\DEV\concat.c [Error] 'abc' undeclared (first use in this function)
25 2 E:\DEV\concat.c [Note] each undeclared identifier is reported only once for each function it appears in
Using if-else statement is an option, but it'll have to be done for many structures and in many places, so i want to avoid that. Please suggest what i am doing wrong or any other way of doing it.
The reason your macro doesn't work is because it results in if (val == 0) structure_1;
which won't compile because you haven't declared a variable. The abc
part isn't injected into the macro, so it only appears at the end of the processed macro expansion: abc
only gets declared as a variable of structure_2
.
This is easily enough fixed: you have to have the variable name as a parameter to your macro as well. Do that and... now the very point has obviously become ruined because your variables exist only inside the if-else blocks which is what you didn't want.
It's at this point that it should become obvious that this simply isn't how C works fundamentally. Genericism isn't well supported, which is a good thing because genericism isn't relevant to what C is trying to accomplish as a language. You should ask yourself why you are trying to force the language to behave this way. What is the point of what you are trying to do?
Regardless, there is a way to get around this in some sense: Unions. Unions allow you to essentially smack different types together into one type. This has the distinct drawback of forcing variables declared from a union to always be the size of the largest type. If you make a union from a 1-byte char and a 100-byte struct, every variable declared will always consume 100-bytes. On the other hand, if you are smacking together same-sized structs, there is no particular penalty.
A simple demonstration:
struct t {
union {
int x; float y;
};
};
int main() {
struct t a = {0};
printf("%d\n", a.x);
printf("%d\n", a.y);
printf("%d\n", sizeof(a)); // 4
return 0;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.