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. (In the absence of an official binding, I think a reasonable rule that would work for most sane C++ programs would be to say any name in ALL_CAPS and any name using the ^_[_[:upper:]].* reserved namespace can be a macro, but other names such as "read", "write", and "link" must not be defined as macros by libc headers. Maybe it would be good to come up with a set of rules for glibc and musl to agree on, if no official POSIX C++ binding is going to happen.) Even if I fix libstdc++ to not require _GNU_SOURCE that won't make the problem go away, because a user could still do: #define _POSIX_SOURCE #include <istream> and if "read" is a macro that will break the declaration of std::istream::read.