bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: identifiers in header files


From: Bruno Haible
Subject: Re: identifiers in header files
Date: Wed, 7 Mar 2007 22:45:22 +0100
User-agent: KMail/1.9.1

Paul Eggert wrote:
> >   extern long double acosl (long double x);
> 
> In proofreading this I noticed that gnulib math.h isn't 100%
> compatible with C99 math.h, since it doesn't allow you to include
> math.h after a perverse macro definition like "#define x char *".
> Other gnulib .h files (e.g., time.h) work around this problem by
> prefixing the parameters with double-underscore

You are looking at it from the perspective of a gnulib user who wants a
<math.h> but the freedom to use identifiers like 'x' and '_x' completely
freely. According to this perspective, gnulib should not use 'x' or '_x'.

The other perspective is from the libc vendors. For them, gnulib is violating
their territory of identifiers if gnulib uses identifiers like '__x'.

So, the "standard"/"C99" argument can be turned in either direction.

gnulib is simply sitting between libc+cc (which claims all '__x' identifiers)
and the programs (which owns all 'x' and '_x' identifiers). So we need to
find a compromise.

I see two ways out of the dilemma:

(a) We don't use such identifiers at all in the headers, and write instead
    extern long double acosl (long double /* x */);

    Please DON'T remove the identifiers entirely, because they are often
    referenced in the comments and also carry a meaning by themselves, if
    there are no comments.

(b) We use identifiers, and choose the convention that minimizes the risks
    of a clash. How many risky identifiers are there? What can we do if
    we have a clash?

    - In /usr/include on a Linux machine I see these:
        ./linux/compiler.h:# define __user
        ./linux/compiler.h:# define __kernel
        ./linux/compiler.h:# define __safe
        ./linux/compiler.h:# define __force
        ./linux/types.h:#define __bitwise
        ./sys/cdefs.h:# define __bounded        /* nothing */
        ./sys/cdefs.h:# define __unbounded      /* nothing */
        ./sys/cdefs.h:# define __ptrvalue       /* nothing */
        ./bits/nan.h:#  define __nan_bytes              { 0x7f, 0xc0, 0, 0 }
        ./bits/nan.h:#  define __nan_bytes              { 0, 0, 0xc0, 0x7f }
        ./linux/compiler-gcc.h:#define __deprecated                     
__attribute__((deprecated))
        ./linux/init.h:#define __init           __attribute__ ((__section__ 
(".init.text")))
        ./linux/init.h:#define __initdata       __attribute__ ((__section__ 
(".init.data")))
        ./linux/init.h:#define __exitdata       __attribute__ 
((__section__(".exit.data")))
      This is just one libc vendor. Do the same on FreeBSD, MacOS X, Woe32,
      etc...

      On the other side, noone has so far complained that he is doing
      "#define x".

    - When we have a clash, it's easier to tell the programmer that uses
      gnulib "hey, don't do '#define user foo'" than it is to tell the
      glibc and Linux people "hey, don't do '#define __user'".

So, for me, we can pretty safely use

     extern long double acosl (long double /* x */);
and
     extern long double acosl (long double x);

Since the second one is prettier (less visual clutter), I prefer that. The
other one can be kept for the case when we really have a clash.

> would you object to 
> doing this consistently, for gnulib headers that mimic standard headers?

Yes. Both alternatives cited above appear to be less risky.

Bruno




reply via email to

[Prev in Thread] Current Thread [Next in Thread]