[Top][All Lists]
[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