Использование gcc.exe (Rev3, созданный проектом MSYS2) 8.2.0.
Я пытался создать макрос для автоматического преобразования типов между двумя типами, где два параметра никогда не должны совпадатьтип.Моя проблема в том, что компилятор выдает ошибку, если я не включаю тот же тип регистра.То, что я хотел:
#include <stdio.h>
#include <stdint.h>
// Macro to return string based on two different types
#define bob( to, from ) \
_Generic( to , \
int32_t: _Generic(from, \
int16_t: "s-l", \
int8_t: "c-l" ) , \
int16_t: _Generic(from, \
int32_t: "l-s", \
int8_t: "c-s") , \
int8_t:_Generic(from, \
int32_t: "l-c", \
int16_t: "s-c") \
)
void main(void)
{
int32_t i1;
int16_t s1;
int8_t c1;
printf("%s\n", bob(i1,s1));
printf("%s\n", bob(i1,c1));
printf("%s\n", bob(s1,c1));
printf("%s\n", bob(s1,i1));
printf("%s\n", bob(c1,s1));
printf("%s\n", bob(c1,s1));
}
$ gcc gbug.c -o gbug.exe
gbug.c: In function 'main':
gbug.c:23:27: error: '_Generic' selector of type 'short int' is not compatible with any association
printf("%s\n", bob(i1,s1));
^~
gbug.c:9:19: note: in definition of macro 'bob'
int16_t: _Generic(from, \
^~~~
gbug.c:24:27: error: '_Generic' selector of type 'signed char' is not compatible with any association
printf("%s\n", bob(i1,c1));
^~
gbug.c:12:17: note: in definition of macro 'bob'
int8_t:_Generic(from, \
^~~~
gbug.c:25:27: error: '_Generic' selector of type 'signed char' is not compatible with any association
printf("%s\n", bob(s1,c1));
^~
gbug.c:12:17: note: in definition of macro 'bob'
int8_t:_Generic(from, \
^~~~
gbug.c:26:27: error: '_Generic' selector of type 'int' is not compatible with any association
printf("%s\n", bob(s1,i1));
^~
gbug.c:6:19: note: in definition of macro 'bob'
int32_t: _Generic(from, \
^~~~
gbug.c:27:27: error: '_Generic' selector of type 'short int' is not compatible with any association
printf("%s\n", bob(c1,s1));
^~
gbug.c:9:19: note: in definition of macro 'bob'
int16_t: _Generic(from, \
^~~~
gbug.c:28:27: error: '_Generic' selector of type 'short int' is not compatible with any association
printf("%s\n", bob(c1,s1));
^~
gbug.c:9:19: note: in definition of macro 'bob'
int16_t: _Generic(from, \
Этот пример является самым простым, который я обнаружил, который потерпит неудачу.
Если я добавлю в "тот же тип"такие строки преобразования:
#define bob( to, from ) \
_Generic( to , \
int32_t: _Generic(from, \
int16_t: "s-l", \
int32_t: "bug", \
int8_t: "c-l" ) , \
int16_t: _Generic(from, \
int32_t: "l-s", \
int16_t: "bug", \
int8_t: "c-s") , \
int8_t:_Generic(from, \
int32_t: "l-c", \
int8_t: "bug", \
int16_t: "s-c") \
)
Создает и работает с ожидаемым результатом:
$ ./gbug.exe
s-l
c-l
c-s
l-s
s-c
s-c
, проверяя, что я не использую макрос для расширения каких-либо условий одного типа.Я понимаю, что _Generic не является макросом для подстановки строк, но я также подумал, что, если бы вы могли использовать его без регистра по умолчанию, он корректно выдавал бы ошибку компиляции, если вы использовали неизвестный тип (или неподдерживаемую комбинацию типов, а именно такое поведение я хотелЭто похоже на то, что препроцессор смешивает два макропараметра.
Редактировать: Итак, у меня есть лучшее понимание (см. Мой ответ ниже), но все еще ищу, как макрос выдает ошибку компиляцииесли два параметра одного типа.До сих пор у меня есть хитрость, чтобы заставить ошибку связи, которая все еще лучше, чем ошибка времени выполнения.