On 04/21/2016 07:20 AM, Jonathan Wakely wrote:
On 21 April 2016 at 13:33, Szabolcs Nagy wrote:
On 21/04/16 12:52, Jonathan Wakely wrote:
On 21 April 2016 at 12:11, Szabolcs Nagy wrote:
the root cause is c++: c++ headers include random libc headers with
_GNU_SOURCE ftm so all sorts of unexpected symbols are defined/declared.

Yes, I'd really like to be able to stop defining _GNU_SOURCE
unconditionally. It needs some libstdc++ and glibc changes for that to
happen, I'll be looking at it for gcc 7.


since it's unlikely the c++ standard gets fixed (to properly specify
the namespace rules)

Fixed how? What's wrong with the rules? (I'd like to understand what's
wrong here before I try to change anything, and I don't understand the
comment above).


posix has "namespace rules" specifying what symbols
are reserved for the implementation when certain
headers are included.
(it's not entirely trivial, i have a collected list
http://port70.net/~nsz/c/posix/reserved.txt
http://port70.net/~nsz/c/posix/README.txt
i use for testing musl headers, glibc also does
such namespace checks.)

e.g. the declared function names in a header are
reserved to be defined as macros.

c++ does not specify how its headers interact with
posix headers except for a few c standard headers
where it requires no macro definition for functions
(and imposes some other requirements on the libc
like being valid c++ syntax, using extern "C" where
appropriate etc).

so from a libc implementor's point of view, including
libc headers into c++ code is undefined behaivour
(neither posix nor c++ specifies what should happen).
without a specification libc headers just piling
#ifdef __cplusplus hacks when ppl run into problems.

e.g. c++ code uses ::pthread_equal(a,b), but musl used
a macro for pthread_equal (the only sensible
implementation is (a)==(b), this has to be suppressed
for c++, which now uses an extern call to do the
same), i'm also pretty sure a large number of c++
code would break if unistd.h defined "read", "write",
"link" etc as macros, since these are often used as
method names in c++, but this would be a conforming
libc implementation.

Gotcha, I understand what you mean now, thanks.

Those rules belong in a POSIX binding for C++, not in the C++
standard, but unfortunately the group working on that has been
inactive for some time.

The binding effort is unfortunately dead.  I don't recall
the group ever discussing the problem of shadow macros but
I think the only viable approach is for C++ code (both the
implementation and user programs) to deal with them.  It
doesn't seem practical to expect POSIX implementations to
change their headers to avoid defining them when __cplusplus
is defined.  In my experience, what works fairly well (but
take quite some effort to implement) is for the C++ standard
library headers to avoid including POSIX headers altogether,
and to guard against the shadow macros interfering with its
own symbols (by parenthesizing their names used in its own
APIs, as ugly as it may look).  This doesn't completely solve
the problem but at least it avoid errors in the C++ standard
library headers and bug reports for them.

Martin

Reply via email to