-static _Noreturn void+static __attribute_noreturn__ voidprint_and_abort (void){/* Don't change any of these strings. Yes, it would be possible to add

But I'm wondering: What is the semantic difference between _Noreturn and__attribute_noreturn__?In the "gcc -E" output, I can see that _Noreturn is present, i.e. is a keyword,and __attribute_noreturn__ expands to __attribute__ ((__noreturn__)).

__attribute__ ((__noreturn__)), which the latter expands to, also works withfunction pointers, whereas _Noreturn does not. The distinction can matter when afunction's address is assigned to a function pointer. Clang checks for__attribute__ ((__noreturn__)) compatibility when assigning function pointers;GCC does not, which can lead to weird results. For example:

In C++ mode, you have to write '[[noreturn]]' instead of _Noreturn, and GCChas a number of bugs in this area:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79604https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80495https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80496

I disagree:1) If _Noreturn does not apply to function pointers, only to functions, weshould better avoid it. It's an ill-defined standard's feature.2) What you call "clang's idiosyncracies" is triggered by our inconsistent usein obstack.c: In one place we use _Noreturn, in the other place we use__attribute__ ((__noreturn__)).In fact, even the GCC documentation does not state that _Noreturn on afunction is equivalent to __attribute__ ((__noreturn__)).

So, at least for obstack.c, I propose to be consistent: use only__attribute__ ((__noreturn__)).

2017-04-23 Bruno Haible <***@clisp.org>

obstack: Avoid clang warning due to inconsistent use of _Noreturn.The code was assuming that _Noreturn and __attribute__((__noreturn__))are equivalent on function definitions, which happens to be true (butundocumented) for GCC, but not for clang.* lib/obstack.c (print_and_abort): Use __attribute_noreturn__.

Post by Bruno Haible1) If _Noreturn does not apply to function pointers, only to functions, weshould better avoid it. It's an ill-defined standard's feature.

Hmm, well, we cannot avoid _Noreturn in general, since the standard requires itfor functions defined by the standard. Admittedly this incompatibility between_Noreturn and __attribute__ ((__noreturn__)) is a pain.

Post by Bruno HaibleSo, at least for obstack.c, I propose to be consistent: use only__attribute__ ((__noreturn__)).

Although this will work for GCC and Clang, I suppose it might cause othercompilers to generate slightly-less-efficient code, because they won't know thatprint_and_abort does not return. To avoid that problem, how about this furtherpatch? If we run into this problem elsewhere we can move the Noreturn macro to amore-public location.

Post by Paul EggertAlthough this will work for GCC and Clang, I suppose it might cause othercompilers to generate slightly-less-efficient code, because they won't know thatprint_and_abort does not return.

Once this is in, how about generalizing it? For other uses than in the module'obstack', I would like to have a module that one can use without #ifdef,without surprises, and that produces best efficient code for all compilers.

It should define two macros:1) a macro for use with function declarations and definitions only,2) a macro for use with function pointers (variables, struct elements etc.).1) would be the __attribute_noreturn__ that we have in obstack.h.2) would be the 'Noreturn' that you define in obstack.c.

And a consistent naming. _GL_NORETURN_FUNC and _GL_NORETURN_FUNCPTR maybe?

Ideally, one should be able to define the same thing, in the same header file,for C++ as well. If the compiler supports C++11 or newer, one can use'[[noreturn]]' instead of '_Noreturn'; otherwise use an empty definitioninstead of '_Noreturn'.

On the other hand, in C, the valid positions of the _Noreturn keyword are_Noreturn extern void foo (void);extern _Noreturn void foo (void);extern void _Noreturn foo (void);So, the only position that works for both C and C++ is the first one:_GL_NORETURN_FUNC extern void foo (void);

Don't some compilers complain if the storage class ('extern', here) isnot first? If so, I suppose we could work around that problem byomitting the 'extern'. As I vaguely recall, the 'extern' is there onlyfor less-important reasons.

If we want to offer a short macro name, such as _GL_NORETURN, it shouldbe usable in both places, function declarations and function pointers.That is, make it an alias of _GL_NORETURN_FUNCPTR.

But that may not work best for function definitions and declarations,for compilers that don't support __attribute__ ((__noreturn__)).Function pointers are relatively rare compared to function definitionsand declarations, so a short name is more-important for the latter.

Post by Bruno HaibleIf we want to offer a short macro name, such as _GL_NORETURN, it shouldbe usable in both places, function declarations and function pointers.That is, make it an alias of _GL_NORETURN_FUNCPTR.

...Function pointers are relatively rare compared to function definitionsand declarations, so a short name is more-important for the latter.

When designing the naming conventions in an API, it's better ignore whichparts of the API will be used frequently or rarely. Better think only athow easy it is to remember each item.

I buy "frequent" vs. "rare" considerations only for the function prototypesand the implementation of an API.

I vaguely recall problems with putting _Noreturn first, maybe forcompilers that lacked native _Noreturn. Why, for example, was this patchmade to clisp in 2011?http://hg.code.sf.net/p/clisp/clisp/rev/c5ba2cfdd7fd?revcount=480

Good point. This patch was a followup ofhttp://hg.code.sf.net/p/clisp/clisp/rev/84e10af84db9I guess I need to test things with some older versions of gcc and g++ as well,and with MSVC, before we can jump to conclusions.

Post by Bruno Haibleit's better ignore whichparts of the API will be used frequently or rarely. Better think only athow easy it is to remember each item.

Even if that's the criterion, I find it easier to remember "use _GL_NORETURN formost noreturn cases, and use _GL_ATTRIBUTE_NORETURN for when you want just thenoreturn attribute" than to remember "use _GL_NORETURN_FUNC for most noreturncases, and use _GL_NORETURN_FUNCPTR for when you want just the noreturnattribute". Partly, I suspect, this is because _GL_ATTRIBUTE_NORETURN followsthe naming convention that _GL_ATTRIBUTE_MALLOC etc. already use.

Post by Bruno Haibleit's better ignore whichparts of the API will be used frequently or rarely. Better think only athow easy it is to remember each item.

Even if that's the criterion, I find it easier to remember "use _GL_NORETURN formost noreturn cases, and use _GL_ATTRIBUTE_NORETURN for when you want just thenoreturn attribute" than to remember "use _GL_NORETURN_FUNC for most noreturncases, and use _GL_NORETURN_FUNCPTR for when you want just the noreturnattribute".

I disagree again. The user should not need to know about whether the macrosexpand to a keyword, an attribute, or whatever. That's part of theirimplementation, which is meant to be opaque.

Seems we can't agree. Therefore I won't propose a short name '_GL_NORETURN'.