They are in fact compatible.
First, section 6.7.6.2p6 of the C standard says the following about the compatibility of array types:
For two array types to be compatible, both shall have compatible
element types, and if both size specifiers are present, and are
integer constant expressions, then both size specifiers shall have the
same constant value. If the two array types are used in a context
which requires them to be compatible, it is undefined behavior if the
two size specifiers evaluate to unequal values.
From this, there is a requirement that if both array sizes are integer constant expressions (i.e. neither is a VLA) then they must be the same. This however does not apply if one is a VLA, so that makes them compatible.
In addition, section 6.2.7p3 says the following regarding composite types:
A composite type can be constructed from two types that are
compatible; it is a type that is compatible with both of the two types
and satisfies the following conditions:
- If both types are array types, the following rules are applied:
- If one type is an array of known constant size, the composite type is an array of that size.
- Otherwise, if one type is a variable length array whose size is specified by an expression that is not evaluated, the behavior is
undefined.
- Otherwise, if one type is a variable length array whose size is specified, the composite type is a variable length array of that size.
- Otherwise, if one type is a variable length array of unspecified size, the composite type is a variable length array of unspecified
size.
- Otherwise, both types are arrays of unknown size and the composite type is an array of unknown size. The element type of the composite
type is the composite type of the two element types.
This means that when comparing the types char(*)[x]
and char(*)[1]
, their composite type is char(*)[1]
. What this also means is that char(*)[x]
is compatible with any pointer to a fixed size array of char
. So if your function looked like this:
void test(int x){
_Static_assert(_Generic( (char(*)[x])0,
char (*)[2]: 2,
char (*)[1]: 1,
default: 0),"");
}
You would get a compilation error because the controlling expression is compatible with multiple options, even though the options are not compatible with each other.