[cfe-dev] Using c++11 features in clang

John McCall rjmccall at apple.com
Thu Jul 5 15:42:53 PDT 2012


On Jul 5, 2012, at 1:09 PM, Eli Friedman wrote:
> On Thu, Jul 5, 2012 at 12:50 PM, Marshall Clow <mclow.lists at gmail.com> wrote:
>> On Jul 5, 2012, at 12:41 PM, Joseph Galbraith wrote:
>> 
>>> On 07/05/2012 12:29, Marshall Clow wrote:
>>>> In response to a some questions on the boost-users list (and boost bug reports), I wrote up this:
>>>>     http://marshall.calepin.co/llvmclang-and-standard-libraries-on-mac-os-x.html
>>>> 
>>>> I don't know if this should be a FAQ entry for Boost, or for clang.
>>>> Suggestions/comments/edits welcome.
>>> 
>>> Isn't one of both of -std=c++11 and -stdlib=libc++ an ABI change?
>>> 
>>> If so, it should probably be noted that all code should be build with
>>> the same settings for these flags.
>> 
>> Yes.
>> 
>>> In particular, I think that you can't pass a std:: classes from libstdc++
>>> built code to libc++ code without bad things happening.
>> 
>> I would expect that also, but libc++ has versioned namespaces that _should_ prevent that from happening (I.e, cause linker errors).
>> 
>>> I'm not sure whether just turning whether the following is safe or not:
>>> 
>>> clang++ -c -stdlib=libc++ x.cpp
>>> clang++ -c -stdlib=libc++ -std=c++11 y.cpp
>>> clang++ -stdlib=libc++ x.o y.o
>> 
>> I would expect either:
>>        * It would "just work"
>>        * It would fail to link
>> 
>> depending on what the contents of x.cpp and y.cpp were.
>> 
>> If you can come up with a good way of explaining this, I'll be happy to add it to my post.
> 
> On OSX specifically, code compiled with -std=c++11 should generally be
> ABI-compatible with code compiled with -std=c++98.  Code compiled with
> -stdlib=libc++ generally isn't ABI-compatible with code compiled with
> -stdlib=libstdc++.

Right.  This is worth expanding on.

If the type signature of a function mentions a stdlib type, then Marshall's
hopes will be fulfilled:  an inline function will get two different implementations
(and therefore "just work"), and a non-inline function will cause a link failure.

(Technically, getting two different implementations can itself cause failures,
e.g. if you're passing the address of the function around.  This is extremely
rare, though.)

However, there are important ways in which code can *rely* on a stdlib type
without making it part of its *signature*:  for example, I could write a function
that takes a Person by reference:
  class Person {
    std::string Name;
    unsigned Age;

  public:
    Person();
    unsigned getAge() const { return Age; }
  };

The layout of this type — its size, and the offset of 'Age' — depends on the
size of std::string, but it will be mangled the same way regardless of the
standard library in play.  Therefore, Person::Person() will simply construct
a Person based on the standard library in effect in the file defining it,
and the two implementations of Person::getAge() will get uniqued by
the linker.

In our experience, it is quite rare to see a program that mixes standard
libraries without *ever* mentioning a stdlib type in the signature of
non-inline function, and so generally users will reliably know if they
screw it up.  Still, it's important to remember that this isn't guaranteed.

John.



More information about the cfe-dev mailing list