[cfe-dev] _LIBCPP_INLINE_VISIBILITY and std::string::length

Alexey Kudinkin alexey.kudinkin at gmail.com
Mon Mar 11 03:06:46 PDT 2013


Sorry, for the not so prompt response.


> On Mar 8, 2013, at 12:18 PM, Howard Hinnant <hhinnant at apple.com> wrote:
> > On Mar 8, 2013, at 2:09 PM, Alexey Kudinkin <alexey.kudinkin at gmail.com>
> wrote:
> >> Hello!
> >>
> >> I'm just curious about what are the reasons to forcing inlining of that
> sort of functions like std::string::length? Precluding them to be included
> into libc++ binary breaks linkage of the following snippet of code
> >>
> >>> int main(int ARGC, char *ARGV[])() {
> >>>
> >>>  std::vector<std::string>  pray = { "I", "will", "not", "aim", "for",
> "the", "head" };
> >>>  std::vector<size_t>       lengths;
> >>>
> >>>  std::transform(pray.begin(), pray.end(), std::back_inserter(lengths),
> std::mem_fn(&std::string::size));
> For what it's worth, IIRC this code is not required to work, because you
> are not generally allowed to take the address of functions from the
> standard library.


However, i believe that since it didn't result in compilation error it is
perfectly clang bug: it seems like it's easily reproducible with extern
templates and __attribute__ (( __always_inline__ )) without involving STL,
and hence rendering pointers/references to the members pretty useless.


On Sat, Mar 9, 2013 at 1:05 AM, John McCall <rjmccall at apple.com> wrote:

> On Mar 8, 2013, at 12:18 PM, Howard Hinnant <hhinnant at apple.com> wrote:
> > On Mar 8, 2013, at 2:09 PM, Alexey Kudinkin <alexey.kudinkin at gmail.com>
> wrote:
> >> Hello!
> >>
> >> I'm just curious about what are the reasons to forcing inlining of that
> sort of functions like std::string::length? Precluding them to be included
> into libc++ binary breaks linkage of the following snippet of code
> >>
> >>> int main(int ARGC, char *ARGV[])() {
> >>>
> >>>  std::vector<std::string>  pray = { "I", "will", "not", "aim", "for",
> "the", "head" };
> >>>  std::vector<size_t>       lengths;
> >>>
> >>>  std::transform(pray.begin(), pray.end(), std::back_inserter(lengths),
> std::mem_fn(&std::string::size));
>
> For what it's worth, IIRC this code is not required to work, because you
> are not generally allowed to take the address of functions from the
> standard library.
>
> > I believe this is due to a poor interaction in the compiler between
> extern templates and __attribute__ ((__always_inline__)).  If std::string
> is not declared extern template, then the compiler will outline a size()
> member and you won't get this link error.
>
> always_inline doesn't stop the dylib from exporting that function symbol.
>  It's the hidden visibility that does that.
>
> > In my opinion, clang should not assume that extern templates have
> definitions for inlined members, especially those marked always_inline, and
> the fact that it does is a clang bug resulting in the link error you see.
>
> Every member of a class template is implicitly inline.  We are not going
> to completely break explicit instantiation declarations.
>
> We do already treat always_inline as a special case, and I'm not sure why
> it's not applying here.  That does seem like a bug.
>
> > The rationale for the use of always_inline in libc++ is to control the
> ABI of libc++.  In the past I have watched compilers use different
> heuristics from release to release on making the inline/outline decision.
>  This can cause code to be silently added to and removed from a dylib.
>  With the use of always_inline, I am telling the compiler to never add that
> code to the libc++.dylib binary.
>
> This is an incredibly brute-force way of accomplishing this goal, and it
> causes major problems downstream, e.g. with debugging programs that use
> libc++.
>
> Have you considered only explicitly instantiating the functions you
> actually want to show up in the library instead of explicitly instantiating
> the entire class?
>
> John.
>



-- 
Best regards,
Alexey Kudinkin.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130311/ac28446e/attachment.html>


More information about the cfe-dev mailing list