On Tue, Dec 3, 2019, 02:31 Bruno Haible <br...@clisp.org> wrote:

> 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.
>

Thank you! Any ideas about the error I mentioned in the first email in this
thread, about mbslen etc.?

Thanks,
Christian


> 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)  \
>
>

Reply via email to