[cfe-dev] RFC: Clang and libstdc++ versions, string.h and cstring conflicts, and glibc patches.

Brooks Moses bmoses at google.com
Thu Aug 29 14:33:43 PDT 2013


Hi all,

So I have this local Clang-related glibc patch that I've been trying
to push upstream, and it's opened a bit of a can of worms that I would
like some advice on....

tl;dr: If string.h in glibc 2.19 checks for __clang__ and breaks
compatibility with libstdc++ 4.3 if it's found, is that bad?  What if
it checks for a recent version of Clang?


The context is straightforward: In C++, some of the functions in
strings.h have different declarations than they do in C.  You can see
this easily in libc++'s cstring, where there's a block of inline
functions that are guarded by an ifdef -- those are there to account
for C++ inclusions of string.h that are not C++-aware.
http://llvm.org/svn/llvm-project/libcxx/trunk/include/cstring

(There's a closely-related issue with wcschr, which was a subject of
another recent email:
http://lists.cs.uiuc.edu/pipermail/cfe-dev/2013-August/031618.html)

Where this gets complicated is in coordinating the C and C++ libraries
to make sure there is only one version of these definitions.
Originally, glibc's headers didn't define these, and so they were
defined in libstdc++ and libc++ headers.  All is good, except for the
fact that glibc's headers contain wrong-for-C++ definitions instead.

In 2009, pre-GCC 4.4, a coordinated pair of patches went in to define
these in glibc and to avoid defining them in libstdc++ if they were
defined in glibc.  But those aren't synchronized projects -- so in
glibc's string.h, these are only defined if the GCC version is 4.4 or
higher, and string.h defines special macros that the libstdc++ headers
use to determine what to do.

This, of course, broke libc++ when compiling with GCC 4.4, which led
to bug 7983; the solution to that was to simply not include the
definitions in cstring when using any version of glibc.  (This breaks
libc++ with older glibc or GCC versions; I presume that was considered
irrelevant.)

And that brings us to the problem we have today: compiling C++ code
with Clang.  Clang reports itself as having compatibility with GCC 4.2
-- and thus glibc's string.h assumes it's dealing with a version-4.2
libstdc++ and exports the old wrong-for-C++ C declarations instead of
the new C++ ones.

This leads to some subtle flavors of sadness, and so we have a
Google-local patch that changes glibc's strings.h check to check for
__clang__ as well as for GCC version of 4.4 or later.  I proposed that
upstream:
http://sourceware.org/ml/libc-alpha/2013-08/msg00556.html

The glibc maintainers pointed out that this will cause problems if
someone is using Clang and glibc 2.19 or later but also using a
libstdc++ that's older than 4.4, or a libc++ before the fix for bug
7983 from late 2010.

So, question 1: Are these use-cases that actually need to be
supported, or are those sufficiently mismatched versions that we can
just say "don't do that"?

One of the glibc maintainers also pointed out that checking for
__clang__ is specific to one non-GCC compiler when there are many that
might be affected, and suggested using __cplusplus >= 199701L instead.
 Because GCC and Clang had defined this with a non-standard value of 1
until recently (May 2012 for Clang), this would apply broadly but only
catch new versions.

Question 2: Would it be objectionable to accept this solution?  It
limits the version combinations that break for question 1 (in that you
now need a new glibc _and_ a new Clang along with the old libstdc++ to
get breakage), but it also means not-new versions of Clang don't get
the fix either.


I'd appreciate any advice and opinions on these.  My inclination is to
reply to the glibc review with a patch that checks __cplusplus, and
call that "good enough".

- Brooks



More information about the cfe-dev mailing list