In C11, there is the keyword _Noreturn
which is a function specifier (like inline
is) that indicates the function does not return — it calls exit()
or equivalent. There is also a header, <stdnoreturn.h>
, the complete definition for which is:
7.23
_Noreturn <stdnoreturn.h>
¶1 The header
<stdnoreturn.h>
defines the macronoreturn
which expands to
_Noreturn
.
In GNU C (GCC), there is an attribute __attribute__((noreturn))
that does essentially the same job. One difference is that __attribute__((noreturn))
can appear before or after the function declarator:
extern __attribute__((noreturn)) void err_error(const char *format, ...);
extern void err_error(const char *format, ...) __attribute__((noreturn));
The problem is that if you include <stdnoreturn.h>
in a translation unit (TU), any subsequent uses of __attribute__((noreturn))
get mapped to __attribute__((_Noreturn))
which then causes the compilation to fail because the attribute _Noreturn
is not recognized (even though the keyword is recognized as a keyword). That is, as far as I can tell, you cannot use both systems at once.
Is there any way around this problem other than either:
<stdnoreturn.h>
, or_Noreturn
keyword?You can detect C11 by testing __STDC_VERSION__ >= 201112L
— the value was specified by Technical Corrigendum 1 because the standard accidentally left the value incompletely specified:
__STDC_VERSION__
The integer constant 201ymmL.178)178) This macro was not specified in ISO/IEC 9899:1990 and was specified as 199409L in ISO/IEC 9899:1990/Amd.1:1995 and as 199901L in ISO/IEC 9899:1999. The intention is that this will remain an integer constant of type
long int
that is increased with each revision of this International Standard.
This can be used to condition the treatment in any one header file, but if you have a mixture of modified and unmodified (C11 and C99) headers, I seem to be running into intractable problems with <stdnoreturn.h>
.
__attribute__((_Noreturn))
be made into a synonym for __attribute__((noreturn))
— which would resolve the problem.Use __attribute__((__noreturn__))
, instead.
All the gcc attributes have a __
version such that you can sanely use them in system headers without polluting the user name space.
Some platform providers also don't seem to be aware of that problem. I recently discovered that for OS X they have the unprotected version in a macro __dead2
.
Also you can't detect the C standard version reliably with the __STDC_VERSION__
macro. All the gcc and clang versions that have a "test" version for C11 that claims C11 if called with -std=c11
without completely implementing it fully. The newer versions are almost there, but only almost.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With