У меня есть структура с объединением и перечислением такого рода. Я создал макрос, который выводит составной литерал структуры, который устанавливает тип и данные объединения в соответствии с типом, передаваемым макросу: _Generi c.
Пример кода:
#include <stdio.h>
struct mystruct {
enum { K_NUM, K_STR } kind;
union { int num; char * str; };
};
#define MYSTRUCT(X) _Generic((X), \
int: (struct mystruct){K_NUM, .num=X}, \
char *: (struct mystruct){K_STR, .str=X} \
)
void print_mystruct(struct mystruct s) {
switch (s.kind) {
case K_NUM: printf("mystruct (num): %d\n", s.num); break;
case K_STR: printf("mystruct (str): %s\n", s.str); break;
}
}
int main() {
print_mystruct(MYSTRUCT(2));
print_mystruct(MYSTRUCT("test"));
}
Он компилируется с g cc, а затем запускается правильно:
mystruct (num): 2
mystruct (str): test
Но я получаю все эти предупреждения компиляции:
c.c: In function 'main':
c.c:21:26: warning: initialization of 'char *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
21 | print_mystruct(MYSTRUCT(2));
| ^
c.c:10:40: note: in definition of macro 'MYSTRUCT'
10 | char *: (struct mystruct){K_STR, .str=X} \
| ^
c.c:21:26: note: (near initialization for '(anonymous).<anonymous>.str')
21 | print_mystruct(MYSTRUCT(2));
| ^
c.c:10:40: note: in definition of macro 'MYSTRUCT'
10 | char *: (struct mystruct){K_STR, .str=X} \
| ^
c.c:22:26: warning: initialization of 'int' from 'char *' makes integer from pointer without a cast [-Wint-conversion]
22 | print_mystruct(MYSTRUCT("test"));
| ^~~~~~
c.c:9:37: note: in definition of macro 'MYSTRUCT'
9 | int: (struct mystruct){K_NUM, .num=X}, \
| ^
c.c:22:26: note: (near initialization for '(anonymous).<anonymous>.num')
22 | print_mystruct(MYSTRUCT("test"));
| ^~~~~~
c.c:9:37: note: in definition of macro 'MYSTRUCT'
9 | int: (struct mystruct){K_NUM, .num=X}, \
| ^
I пробовал приводить составные литералы примерно так:
int: (struct mystruct){K_NUM, .num=(int)X}, \
char *: (struct mystruct){K_STR, .str=(char *)X} \
Но я получаю разные предупреждения:
c.c: In function 'main':
c.c:9:37: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
9 | int: (struct mystruct){K_NUM, .num=(int)X}, \
| ^
c.c:22:17: note: in expansion of macro 'MYSTRUCT'
22 | print_mystruct(MYSTRUCT("test"));
| ^~~~~~~~