I’ve encountered unexpected behavior when using _Generic
in C with compound literals. It appears that _Generic
picks the first case that contains a compound literal, regardless of whether it matches the actual type of the expression. This happens even though other cases should match more precisely.
Consider the following code:
typedef struct { unsigned char _dummy_m[3]; } int24_t;
#define GET_VALUE_ADDRESS(v) _Generic((v), \
int*: &(v), \
double: &(double){v}, \
int24_t: &(v), \
default: &(v))
int main (void)
{
int24_t val = {1,2,3};
void* addr = GET_VALUE_ADDRESS(val); /* erroneous */
return 0;
}
The compiler is MinGW-GCC Rev2, Built by MSYS2 project 10.3.0 and with the following CMake configuration:
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_EXTENSIONS ON)
The code produces the following error:
incompatible types when initializing type 'double' using type 'int24_t'
Expected Behavior:
In this example, v
is of type int24_t
, so I expect _Generic
to match the int24_t
case and return &(v)
.
Actual Behavior:
Instead, the compiler seems to always pick the first case that involves a compound literal (in this case, &(double){v}
), regardless of the type of v
. This results in incorrect type matching and an unexpected output.
Additional Information:
If I remove the compound literal(s) and replace them with regular address-of operations, _Generic
works as expected. The issue only arises when using compound literals as the return value in _Generic
.
Question:
Even if this is not a bug or quirk in _Generic
itself, still the error I am getting is nothing short of unhelpful.
Is this a known bug or a limitation in how _Generic handles compound literals? If so, is there any workaround, or am I misusing _Generic
in this context?
You need to sign in to view this answers