GCC 6 symbol poisoning and c++ header usage is fragile

Martin Sebor msebor@gmail.com
Fri Apr 22 15:06:00 GMT 2016


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



More information about the Gcc mailing list