Hi, I'm compiling gnulib 23eecb48e39afd0d267d64d40ba6bf97aa865e13 with gcc-4.6, and using it from a C++ project compiled with g++-4.6 -std=c++0x
When I attempt to include argp.h, compilation fails: % cat foo.cc #include "config.h" #include "argp.h" % g++-4.6 -DHAVE_CONFIG_H -Ilib -Wall -Werror -std=c++0x -c foo.cc In file included from foo.cc:2:0: lib/argp.h:623:1: error: ‘__leaf__’ attribute has no effect on unit local functions [-Werror=attributes] lib/argp.h:635:1: error: ‘__leaf__’ attribute has no effect on unit local functions [-Werror=attributes] Looking at the preprocessed output, I can see that the two functions : ARGP_EI int : __NTH (__option_is_short (const struct argp_option *__opt)) : /* ... */ : ARGP_EI int : __NTH (__option_is_end (const struct argp_option *__opt)) were expanded as: : static __attribute__ ((__unused__)) int : __attribute__ ((__leaf__)) _option_is_short (const struct argp_option *__opt) throw () : /* ... */ : static __attribute__ ((__unused__)) int : __attribute__ ((__leaf__)) _option_is_end (const struct argp_option *__opt) throw () So __leaf__ was indeed applied to a static function. This "static" comes from the expansion of ARGP_EI: #define ARGP_EI _GL_INLINE /* in argp.h */ #define _GL_INLINE static _GL_UNUSED /* in config.h */ #define _GL_UNUSED __attribute__ ((__unused__)) /* in config.h */ The warning disappears if I use g++-4.6 without the -std=c++0x option. In this case these prototypes become: : extern inline __attribute__ ((__gnu_inline__)) int : __attribute__ ((__leaf__)) _option_is_short (const struct argp_option *__opt) throw () : /* ... */ : extern inline __attribute__ ((__gnu_inline__)) int : __attribute__ ((__leaf__)) _option_is_end (const struct argp_option *__opt) throw () because now config.h has #define _GL_INLINE extern inline __attribute__ ((__gnu_inline__)) The warning also disappear if I use g++-4.7 -std=c++0x. Then we get: : inline int : __attribute__ ((__leaf__)) _option_is_short (const struct argp_option *__opt) throw () : /* ... */ : inline int : __attribute__ ((__leaf__)) _option_is_end (const struct argp_option *__opt) throw () with #define _GL_INLINE inline /* in config.h */ (The difference between 4.6 -std=c++0x and 4.7 -std=c++0x is that the former defines __GNUC_GNU_INLINE__ while the latter defines __GNUC_STDC_INLINE__.) Comments: 1. I do not understand the effect of marking an inline function as leaf, or as nothrow. Shouldn't these attributes be only used to help the compiler when a function is declared, but its body is unknown? 2. Shouldn't _GL_INLINE/_GL_EXTERN_INLINE simply always expand to 'inline' in C++? I've patched my copy of argp.h as suggested in point 1 above to fix my compilation issue (patch attached). But as the implication of __NTH in conjunction with _GL_INLINE is unclear to me, I'm not sure whether this is sane. -- Alexandre Duret-Lutz
From c072aaf3ed47169105fbb23dec64644e4277d9ec Mon Sep 17 00:00:00 2001 From: Alexandre Duret-Lutz <a...@lrde.epita.fr> Date: Wed, 18 Dec 2013 13:35:21 +0100 Subject: [PATCH] argp: fix compilation with g++-4.6 -std=c++0x. * lib/argp.h (__option_is_short, __option_is_end) Do not declare with __NTH. The 'leaf' attribute is unwelcome in the case ARGP_EI is implemented with 'static' (this occurs when compiling argp.hh with g++-4.6 -std=c++0x). --- ChangeLog | 9 +++++++++ lib/argp.h | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1753c8e..8dbcdf3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2013-12-18 Alexandre Duret-Lutz <a...@lrde.epita.fr> + + argp: fix compilation with g++-4.6 -std=c++0x. + + * lib/argp.h (__option_is_short, __option_is_end) Do not declare + with __NTH. The 'leaf' attribute is unwelcome in the case ARGP_EI + is implemented with 'static' (this occurs when compiling argp.hh + with g++-4.6 -std=c++0x). + 2013-12-17 Paul Eggert <egg...@cs.ucla.edu> gettimeofday: port recent C++ fix to Emacs diff --git a/lib/argp.h b/lib/argp.h index a5f686a..99ea26a 100644 --- a/lib/argp.h +++ b/lib/argp.h @@ -620,7 +620,7 @@ __argp_usage (const struct argp_state *__state) } ARGP_EI int -__NTH (__option_is_short (const struct argp_option *__opt)) +__option_is_short (const struct argp_option *__opt) { if (__opt->flags & OPTION_DOC) return 0; @@ -632,7 +632,7 @@ __NTH (__option_is_short (const struct argp_option *__opt)) } ARGP_EI int -__NTH (__option_is_end (const struct argp_option *__opt)) +__option_is_end (const struct argp_option *__opt) { return !__opt->key && !__opt->name && !__opt->doc && !__opt->group; } -- 1.8.5.1