У меня есть (сложный) код, который работает на компиляторе IAR. Я принял участие в этом коде, чтобы создать фрагмент для его улучшения. Но при переносе части этого кода на онлайн-компилятор он не будет компилироваться.
«error: '_Generic' указывает два совместимых типа»
, поскольку я использовал _Generi c как этот пример:
#define GET_TYPE_(data) _Generic((&data)+0, \
_Bool * : TYPE_BOOL_, \
uint8_t* : TYPE_U8_, \
uint16_t* : TYPE_U16_, \
uint32_t* : TYPE_U32_, \
someEnum1_e* : TYPE_BOOL_, \
someEnum2_e* : TYPE_SPECIAL_A, \
someEnum3_e* : TYPE_SPECIAL_B, \
default: TYPE_DEFAULT_ )
С TYPE_XXX, являющимся #define, я могу вызвать
switch(GET_TYPE_(myVariable))
{
case TYPE_XXXX: do_something(); break;
...
}
Но когда я переместил его с помощью онлайн-компилятора (онлайн-GDB) с помощью g cc, я получил ошибку:
error: ‘_Generic’ specifies two compatible types
someEnum1_e* : TYPE_BOOL_, \
error: ‘_Generic’ specifies two compatible types
someEnum2_e* : TYPE_SPECIAL_A, \
error: ‘_Generic’ specifies two compatible types
someEnum3_e* : TYPE_SPECIAL_B, \
Я прочитал, что это нормальное поведение и что оно не должно компилироваться. Тем не менее, как это можно скомпилировать в IAR?
(да, я прошу вас поверить мне без воспроизводимого рабочего примера, потому что я не предоставлю свой пропреторный код)
Редактировать: Вкл. Годболт :
- x86-64 clang 10,: код работает только на С ++! и в C выдает похожую ошибку:
"type 'someEnum1_e*' in generic association compatible with previously specified type 'uint32_t *' (aka 'unsigned int *')"
- ARM64 G CC 8.2, флаг -std = c11: код выдает ошибку
- x64 G CC 9.3, флаг -std = c11: код выдает ошибку
- AVR G CC 5.4, флаг -std = c11: код не распознает _Generi c, ни _Bool:
"error: '_Generic' was not declared in this scope"
- MSP430 G CC 6.2.1, флаг -std = c11: код работает! (но не в C ++)
- и на моем компьютере с IAR 8.20.2, флаг -std = c11: код работает!
1-й бонусный вопрос : Это может быть ошибка компилятора? Что говорится в стандарте?
2-й бонусный вопрос: есть ли способ избежать ошибки? (для всех компиляторов)
Короткий фрагмент для проверки моих высказываний
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
typedef enum
{
ENUM1_A,
ENUM1_B,
}someEnum1_e;
#define TYPE_E1_ 0
#define TYPE_U32_ 1
#define GET_TYPE_(data) _Generic((&data)+0, \
uint32_t* : TYPE_U32_, \
someEnum1_e* : TYPE_E1_, \
default: TYPE_U32_ )
int main (void)
{
uint32_t foo;
someEnum1_e bar;
switch(GET_TYPE_(foo)){default:break;};
switch(GET_TYPE_(bar)){default:break;};
}