A compound literal has the form `(T){ INIT }`: a type in parentheses followed by an initializer. It defines an unnamed object of type `T`; it is not merely a value written in a different notation. For example, `(size_t){ 3 }` defines a `size_t` object initialized to 3. section 5.6.4
# define CORVID_NAME /**/ \
(char const*const[corvid_num]){ \
[chough] = "chough", \
[raven] = "raven", \
[magpie] = "magpie", \
[jay] = "jay", \
}
This macro replaces its name with an array compound literal. The initializer supplies names at designated indices, so an expression such as `CORVID_NAME[i]` can select one. The space before the compound literal prevents the macro from being parsed as function-like. section 5.6.4
TAKEAWAY: A compound literal defines an object, not an integer constant expression. When a macro is intended to behave like a named constant, qualify its type with `const`, but do not assume that makes it suitable wherever a compile-time constant is required. Macro definitions are text replacement: omit a terminating semicolon from the replacement. section 5.6.4
Check a macro argument's type
The pattern `((T){ (X) })` initializes a temporary object of type `T` from `X`. Unlike a cast, initialization requires `X` to be assignment-compatible with `T`. With `T` as `void*`, this can check a pointer argument before it is printed with `%p`; a cast would suppress the intended type check. An optimizing compiler can remove the temporary object's runtime cost. section 17.2
An address taken from a compound literal must not outlive its object:
- In a `while` body, each iteration defines a new local instance. A pointer assigned `&(size_t){ fun() }` there cannot validly dereference that object after the loop. section 19.3
- A repeated statement reached by `goto` can instead leave the object alive until the surrounding block ends. The pointer can remain usable, but the object retains resources longer. section 19.3
C23 also permits `constexpr` on a compound literal. This supplies a compile-time-checked constant for uses such as an initializer at file scope; its initializer must fit exactly, and `const` qualification is implied. section 5.6.5

