Pierre HABOUZIT <madcoder@debian.org> writes: > tag 377416 + moreinfo > thanks > > On Sat, Jul 08, 2006 at 08:14:35PM +0100, Roger Leigh wrote: >> Package: libc6-dev >> Version: 2.3.6-15 >> Severity: important >> >> # if !defined __cplusplus && __GNUC_PREREQ (3, 3) >> # define __THROW __attribute__ ((__nothrow__)) XXXX >> # define __NTH(fct) __attribute__ ((__nothrow__)) fct >> # else >> # if defined __cplusplus && __GNUC_PREREQ (2,8) >> # define __THROW throw () >> # define __NTH(fct) fct throw () >> # else >> # define __THROW >> # define __NTH(fct) fct >> # endif >> # endif >> >> The line marked with XXXX expands incorrectly: >> >> void f() __THROW >> ==> void f() __attribute__ ((__nothrow__)) >> >> instead of void __attribute__ ((__nothrow__)) f() > > I'm not sure to understand where the problem is. I thought I explained the problem adequately in the bug report. Look at the example in the very first entry. The versions for GCC >= 3.3 are totally different from >= 2.8. GCC function attributes are specified *before* the function name, and yet the GCC >= 2.8 variation uses throw() which is used *after* the function name and arguments. As a result, it it will break depending upon the compiler version, because wherever you put __THROW it will always be broken on one compiler. You'll see __NTH gets it right, because you give it the function name and it can place the expansion on the correct side. For further information: Check for all the definitions of __THROW and __NTH in /usr/include: hardknott% rgrep 'define[[:space:]]*__THROW' /usr/include /usr/include/argp.h:# define __THROW /usr/include/malloc.h:# define __THROW throw () /usr/include/malloc.h:# define __THROW /usr/include/malloc.h:# define __THROW /usr/include/getopt.h:# define __THROW throw () /usr/include/getopt.h:# define __THROW /usr/include/sys/cdefs.h:# define __THROW __attribute__ ((__nothrow__)) /usr/include/sys/cdefs.h:# define __THROW throw () /usr/include/sys/cdefs.h:# define __THROW /usr/include/sys/cdefs.h:# define __THROW hardknott% rgrep 'define[[:space:]]*__NTH' /usr/include /usr/include/argp.h:# define __NTH(fct) fct __THROW /usr/include/sys/cdefs.h:# define __NTH(fct) __attribute__ ((__nothrow__)) fct /usr/include/sys/cdefs.h:# define __NTH(fct) fct throw () /usr/include/sys/cdefs.h:# define __NTH(fct) fct /usr/include/sys/cdefs.h:# define __NTH(fct) fct Next, check each one and compare them. You'll see that each is different, so depending upon the header include order, you'll get a different definition. Some include version checks for different GCC versions, and others include /different/ version checks and definitions. This is a mess. Some, as this bug report highlights, are broken under some circumstances, so the programmer is screwed however they use __THROW. The circumstances resulting in this bug report are in fact building glibc itself. In some cases, this can cause severe problems. See #340871 for an extreme example, where it broke the m68k build. The patch that fixed it required inserting *yet another* __THROW definition due to the above problems. See http://bugs.debian.org/cgi-bin/bugreport.cgi/local-mathinline_h.diff?bug=340871;msg=137;att=2 Ideally, glibc should provide one (and one only) definition of __THROW and __NTH, which all the other headers can include. The current situation is that __THROW and __NTH can randomly break, because you can't be sure which definition got defined first. As a result, this brokenness really needs cleaning up. Regards, Roger -- .''`. Roger Leigh : :' : Debian GNU/Linux http://people.debian.org/~rleigh/ `. `' Printing on GNU/Linux? http://gutenprint.sourceforge.net/ `- GPG Public Key: 0x25BFB848 Please GPG sign your mail.
Attachment:
pgpFUDZTrpUrj.pgp
Description: PGP signature