Why does emplace_back(“Hello”) call strlen?

*爱你&永不变心* 提交于 2019-12-10 12:53:07

问题


Justin's answer on another question made an observation that I find very interesting but can't quite explain. Consider the following code:

std::vector<std::string> v;
v.push_back("Hello, world!");  // Doesn't call strlen.
v.emplace_back("Hello, world!");  // Calls strlen.

If you look at the assembly, emplace_back generates a call to strlen, whereas push_back does not (tested in gcc 8.1 and clang 6.0 using -Ofast).

Why is this happening? Why can't emplace_back optimize out the strlen call here? My initial thought was that push_back is implicitly creating the std::string before the function call (so the std::string constructor is directly passed the string literal, which is optimally handled), whereas emplace_back creates the std::string after the function call (so the std::string constructor is forwarded the string literal, which I presumed had decayed from a const char [N] to a const char *, thus requiring a strlen call).

But emplace_back takes a T&& parameter, and my tests show that the string literal shouldn't be decaying to a pointer here. Clearly I'm overlooking something.


回答1:


The strlen call is in the out-of-line function body for the slow path; that function body must be valid for all arguments of type const char (&)[42] (in your godbolt example), including arguments that did not originate from a string literal of 41 characters with no embedded nulls.

The fast path is inlined into foo, and it does compute the length at compile time.



来源:https://stackoverflow.com/questions/51219755/why-does-emplace-backhello-call-strlen

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!