[cfe-dev] RFC: Clang and libstdc++ versions, string.h and cstring conflicts, and glibc patches.
"C. Bergström"
cbergstrom at pathscale.com
Thu Aug 29 16:56:58 PDT 2013
On 08/30/13 04:33 AM, Brooks Moses wrote:
> 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.
/*
libstdc++ consumer older than 4.4... those people get what they deserve ;)
*/
>
> 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.
Sorry for the peanut gallery comment, but this isn't exactly true...
Anyone using a clang based front-end will probably be forced to define
__clang__. This isn't common, but there's at least 1 and possibly 2 or
more non-llvm based compilers doing this that I'm aware of. In the cases
that I'm aware of - those modified versions of clang are post-may-2012
though.
please don't depend on non-standard values though...
(PathScale compiler is recent modified clang + recent libc++ || STDCXX
and while we could in theory play nice with the system libstdc++, we
don't ever use it beyond some internal testing.)
>
> 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.
Your solution and limitations seem reasonable to me (for whatever that's
worth)
I think if someone *really* cared about that older version of clang they
could - a) backport the fix or b) submit a patch after yours. Unlike GCC
which has some caveats between releases - clang's evolution is quite
"stable" and I don't know of any solid arguments which force people not
to update.
>
>
> 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".
please no non-standard or standard breaking things (I prefer either
option 1 or 2 below)
1) introduce yet another -D define
2) go with a __clang__ version check
3) if you explicitly want this to only apply to clang+llvm - then add a
check for llvm's define as well
More information about the cfe-dev
mailing list