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?
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:
...
or not, and the corresponding parameter types are compatible (after removing qualifiers from the parameter types and adjusting function and array types to pointers).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.