Search code examples
clanguage-lawyerfunction-declarationnoreturn

Declaring a function with different function specifiers


Consider this C code:

_Noreturn void exit(int status);
void exit(int status);

int main(void) {
    exit(0);
}

It declares the exit function twice, once with the _Noreturn function specifier, and once without. This seems like it should be Undefined Behavior, but I can't find anything concrete in the standard that says so, and I don't get any compiler warnings about it no matter how high I set my warning level. Is it actually UB, or is it okay? And since the C standard says exit is _Noreturn, if I only had the declaration that doesn't have that, would that be UB or okay?


Solution

  • Is it actually UB, or is it okay?

    Presumably you are concerned about whether these declarations violate some rule regarding declaring identifiers twice, notably compatibility. C 2018 6.2.7 2 says:

    All declarations that refer to the same object or function shall have compatible type; otherwise, the behavior is undefined.

    The rules for compatibility of function types are specified in C 2018 6.7.6.3 15. Briefly, they say:

    • The return types shall be compatible.
    • If they both have parameter type lists, the lists have the same number of parameters, both have ... or not, and the corresponding parameter types are compatible (after removing qualifiers from the parameter types and adjusting function and array types to pointers).
    • Otherwise, the parameter parts of the declarations have to satisfy various requirements that do not concern us here.

    These rules do not say the function specifiers have to satisfy any requirements. So the two declarations you show declare exit with compatible types and therefore satisfy 6.2.7 2.

    And since the C standard says exit is _Noreturn, if I only had the declaration that doesn't have that, would that be UB or okay?

    It does not appear to violate any rule in C 2018. As Jonathan Leffler’s answer notes, this changes in the expected C 2023 standard.