Clang++ always defines _GNU_SOURCE

Hi,

I noticed that clang++ unconditionally defines _GNU_SOURCE on Linux,
even when I'm not including any headers in my code. Switching from
stdlibc++ to libc++ doesn't change this, either.

I understand that g++ does this because stdlibc++ heavily relies on
_GNU_SOURCE. But what is the reason for clang++ to do so when using
libc++? Does libc++ also rely on this macro to work on Linux?

Regards,
Lei

Does libc++ also rely on this macro to work on Linux?

Yes. Adding -U_GNU_SOURCE during the libc++ build results in a litany of errors.
The libc++ headers depend on a number of C library symbols that only get defined when -D_GNU_SOURCE=1 is present.

/Eric

I would assume that many of the same stupid visibility restrictions
apply to libc++ just as well.

Joerg

Is it feasible to use some finer-grain control like _ISOC99_SOURCE,
instead of resorting to the too versatile _GNU_SOURCE?

I'd be willing to work out such a patch to libc++, if it makes sense.

Lei

Hi,

Does libc++ also rely on this macro to work on Linux?

Yes. Adding -U_GNU_SOURCE during the libc++ build results in a litany of
errors.
The libc++ headers depend on a number of C library symbols that only get
defined when -D_GNU_SOURCE=1 is present.

Is it feasible to use some finer-grain control like _ISOC99_SOURCE,
instead of resorting to the too versatile _GNU_SOURCE?

I'd be willing to work out such a patch to libc++, if it makes sense.

Note that _GNU_SOURCE is more extensive:

(from glibc's features.h)

/* If _GNU_SOURCE was defined by the user, turn on all the other features. */
#ifdef _GNU_SOURCE
# undef _ISOC95_SOURCE
# define _ISOC95_SOURCE 1
# undef _ISOC99_SOURCE
# define _ISOC99_SOURCE 1
# undef _ISOC11_SOURCE
# define _ISOC11_SOURCE 1
# undef _POSIX_SOURCE
# define _POSIX_SOURCE 1
# undef _POSIX_C_SOURCE
# define _POSIX_C_SOURCE 200809L
# undef _XOPEN_SOURCE
# define _XOPEN_SOURCE 700
# undef _XOPEN_SOURCE_EXTENDED
# define _XOPEN_SOURCE_EXTENDED 1
# undef _LARGEFILE64_SOURCE
# define _LARGEFILE64_SOURCE 1
# undef _DEFAULT_SOURCE
# define _DEFAULT_SOURCE 1
# undef _ATFILE_SOURCE
# define _ATFILE_SOURCE 1
#endif

Regards,
ismail

Yes, it requires the use of multiple different finer-grain macros to
replace _GNU_SOURCE, but it's worth the effort IMHO. Simply defining
_GNU_SOURCE may pollute users' code with many unwanted symbols.

Lei

That is the better approach. The problem is that we tend to lump groups
of functions under macros like _GNU_SOURCE or __UCLIBC__ only to run
into problems later.

Compared to breaking lots of applications that expect the GNU symbols by
default?

Joerg

That's a valid point. OTOH, should we encourage applications to use
GNU symbols with out explicitly defining _GNU_SOURCE? Then what's the
point of such a macro?

Lei

BTW, _GNU_SOURCE is *not* unconditionally defined by gcc/clang when
compiling C code on Linux.

Lei

You can't change the visibility macros after the first header has been
included. C language mode doesn't ship with a C library set that
requires many of the non-standard / non-ISO functions. That's completely
different from C++, where many typical STL includes include more than
the functions supported by ISO C (and the default namespace with glibc).
That's why it is pushed by default.

Joerg

Perhaps I'm not seeing the whole picture, but it looks to me that
using finer-grained visibility macros like _BSD_SOURCE,
_POSIX_C_SOURCE, etc does *not* violates your points. We could still
expose those non-standard functions without blindly defining
_GNU_SOURCE, don't we?

Lei

Except when the standards conflict or the other already specified
something else, e.g. POSIX 2004.

Joerg