cgenericsc11

Understanding C11's _Generic


The C17 Standard requires that, in a _Generic expression,

No two generic associations in the same generic selection shall specify compatible types. The type of the controlling expression is the type of the expression as if it had undergone an lvalue conversion [....]

@Davilsor in this post: https://codereview.stackexchange.com/a/289337/265278 states that:

_Generic is really only intended to make the implementation of <math.h> more portable, so I don’t entirely trust it with integral types. I’d be especially wary of char and short int getting widened to int.

If uint64_t is a typedef for say unsigned long long int, and I have both of them in some _Generic expression, would that go against "No two generic associations in the same generic selection shall specify compatible types"? If it does, what behavior should I expect? Compilation to fail? Undefined Behavior? A diagnostic?

Take this for example:

#define map(count, iter, func) _Generic (*iter,   \
                                char: map_c,    \
                                unsigned char: map_uc,  \
                                short int: map_si,   \
                                unsigned short int: map_usi,    \
                                int: map_i, \
                                unsigned int: map_ui,   \
                                long int: map_li,   \
                                unsigned long int: map_uli, \
                                long long int: map_lli,     \
                                unsigned long long int: map_ulli,   \
                                float: map_f,   \
                                double: map_d,  \
                                long double: map_ld,    \
                                _Bool: map_b,    \
                                char *: map_s   \
                            )(count, iter, func)

Is there anything that could potentially go wrong in the above _Generic expression, especially if I add fixed-width integer types from stdint.h to it?


Solution

  • If uint64_t is a typedef for say unsigned long long int, and I have both of them in some _Generic expression, would that go against "No two generic associations in the same generic selection shall specify compatible types"?

    Yes.

    If it does, what behavior should I expect? Compilation to fail? Undefined Behavior? A diagnostic?

    A diagnostic message and most compilers will refuse to compile the program.

    Is there anything that could potentially go wrong in the above _Generic expression,

    No, not as its currently written.

    especially if I add fixed-width integer types from stdint.h to it?

    Yes, then you will have problems since you will then specify the same type more than once so you'll get diagnostic messages and the program will likely fail to compile.