Compiling a C++ file that includes xalloc.h, I get an error on FreeBSD 12: In file included from ../../gltests/test-list-c++.cc:20: In file included from ../../gltests/../gllib/gl_list.hh:22: In file included from ../../gltests/../gllib/gl_xlist.h:22: ../../gltests/../gllib/xalloc.h:51:8: error: an attribute list cannot appear here extern _Noreturn void xalloc_die (void); ^~~~~~~~~ /usr/include/sys/cdefs.h:280:20: note: expanded from macro '_Noreturn' #define _Noreturn [[noreturn]] ^~~~~~~~~~~~ 1 error generated. *** Error code 1
The reason is as explained in [1]: While the syntax [[noreturn]] void func (...); and [[noreturn]] extern void func (...); are valid in C++, the syntax extern [[noreturn]] void func (...); is not. (clang and MSVC give an error, and gcc a warning.) One more example of how terrible C++ is at the syntactic level. In this case, however, the definition of _Noreturn comes from the system. I don't think it would be adequate to override it. So, fix the gnulib header instead. [1] https://lists.gnu.org/archive/html/bug-gnulib/2019-12/msg00013.html 2020-02-02 Bruno Haible <br...@clisp.org> xalloc: Fix compilation error in C++ mode on FreeBSD 12. * lib/xalloc.h (xalloc_die): Comment out 'extern' keyword before '_Noreturn'. * lib/sigpipe-die.h (sigpipe_die): Likewise. diff --git a/lib/xalloc.h b/lib/xalloc.h index 9563b0b..19c64ac 100644 --- a/lib/xalloc.h +++ b/lib/xalloc.h @@ -48,7 +48,7 @@ extern "C" { or by using gnulib's xalloc-die module. This is the function to call when one wants the program to die because of a memory allocation failure. */ -extern _Noreturn void xalloc_die (void); +/*extern*/ _Noreturn void xalloc_die (void); void *xmalloc (size_t s) _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1)); diff --git a/lib/sigpipe-die.h b/lib/sigpipe-die.h index dcb9a4a..7fcde8c 100644 --- a/lib/sigpipe-die.h +++ b/lib/sigpipe-die.h @@ -48,7 +48,7 @@ extern "C" { /* Emit an error message indicating a SIGPIPE signal, and terminate the process with an error code. */ -extern _Noreturn void sigpipe_die (void); +/*extern*/ _Noreturn void sigpipe_die (void); /* Install a SIGPIPE handler that invokes PREPARE_DIE and then emits an error message and exits. PREPARE_DIE may be NULL, meaning a no-op. */