Hi Christian, > $ /opt/IBM/xlC/16.1.0/bin/xlclang++ test.cc -I gnulib/import -I > ../gnulib/import/ > In file included from test.cc:2: > In file included from gnulib/import/stdlib.h:36: > In file included from /opt/IBM/xlC/16.1.0/include2/c++/stdlib.h:94: > /opt/IBM/xlC/16.1.0/include2/aix/stdlib.h:310:9: error: an attribute > list cannot appear here > extern _Noreturn void exit(int); > ^~~~~~~~~ > ./gnulib/config.h:1117:21: note: expanded from macro '_Noreturn' > # define _Noreturn [[noreturn]] > ^~~~~~~~~~~~ > In file included from test.cc:2: > In file included from gnulib/import/stdlib.h:36: > In file included from /opt/IBM/xlC/16.1.0/include2/c++/stdlib.h:94: > /opt/IBM/xlC/16.1.0/include2/aix/stdlib.h:319:9: error: an attribute > list cannot appear here > extern _Noreturn void quick_exit(int); > ^~~~~~~~~ > ./gnulib/config.h:1117:21: note: expanded from macro '_Noreturn' > # define _Noreturn [[noreturn]] > ^~~~~~~~~~~~ > 2 errors generated.
Oh boy. 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. Since not only the aforementioned AIX header file, but also several gnulib header files use the 'extern' keyword consistently (in a good way), the only choice we have is to not use '[[noreturn]]' - except in noreturn.h which documents the allowed syntaxes clearly. 2019-12-03 Bruno Haible <br...@clisp.org> Avoid hassles caused by [[noreturn]] in C++. Reported by Christian Biesinger <cbiesin...@google.com> in <https://lists.gnu.org/archive/html/bug-gnulib/2019-12/msg00010.html>. * m4/gnulib-common.m4 (gl_COMMON_BODY): Disable the use of [[noreturn]]. * lib/_Noreturn.h: Likewise. diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4 index 479c9de..d8f0d3f 100644 --- a/m4/gnulib-common.m4 +++ b/m4/gnulib-common.m4 @@ -1,4 +1,4 @@ -# gnulib-common.m4 serial 45 +# gnulib-common.m4 serial 46 dnl Copyright (C) 2007-2019 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -19,7 +19,14 @@ AC_DEFUN([gl_COMMON_BODY], [ #ifndef _Noreturn # if (defined __cplusplus \ && ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \ - || (defined _MSC_VER && 1900 <= _MSC_VER))) + || (defined _MSC_VER && 1900 <= _MSC_VER)) \ + && 0) + /* [[noreturn]] is not practically usable, because with it the syntax + extern _Noreturn void func (...); + would not be valid; such a declaration would only be valid with 'extern' + and '_Noreturn' swapped, or without the 'extern' keyword. However, some + AIX system header files and several gnulib header files use precisely + this syntax with 'extern'. */ # define _Noreturn [[noreturn]] # elif ((!defined __cplusplus || defined __clang__) \ && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \ diff --git a/lib/_Noreturn.h b/lib/_Noreturn.h index 06320b8..d99e377 100644 --- a/lib/_Noreturn.h +++ b/lib/_Noreturn.h @@ -17,7 +17,14 @@ #ifndef _Noreturn # if (defined __cplusplus \ && ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \ - || (defined _MSC_VER && 1900 <= _MSC_VER))) + || (defined _MSC_VER && 1900 <= _MSC_VER)) \ + && 0) + /* [[noreturn]] is not practically usable, because with it the syntax + extern _Noreturn void func (...); + would not be valid; such a declaration would only be valid with 'extern' + and '_Noreturn' swapped, or without the 'extern' keyword. However, some + AIX system header files and several gnulib header files use precisely + this syntax with 'extern'. */ # define _Noreturn [[noreturn]] # elif ((!defined __cplusplus || defined __clang__) \ && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \