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

Reply via email to