Example of the perils of binding rvalues to const ref

Sean Kelly via Digitalmars-d digitalmars-d at puremagic.com
Tue Sep 16 16:17:17 PDT 2014


On Tuesday, 16 September 2014 at 15:30:49 UTC, Andrei
Alexandrescu wrote:
> http://www.slideshare.net/yandex/rust-c
>
> C++ code:
>
> std::string get_url() {
>     return "http://yandex.ru";
> }
>
> string_view get_scheme_from_url(string_view url) {
>     unsigned colon = url.find(':');
>     return url.substr(0, colon);
> }
>
> int main() {
>     auto scheme = get_scheme_from_url(get_url());
>     std::cout << scheme << "\n";
>     return 0;
> }
>
> string_view has an implicit constructor from const string& (see 
> "basic_string_view(const basic_string<charT, traits, 
> Allocator>& str) noexcept;" in 
> https://isocpp.org/files/papers/N3762.html). The function 
> get_url() returns an rvalue, which in turn gets bound to a 
> reference to const and implicitly passed to string_view's 
> constructor. The obtained view refers to a dead string.

That's a design mistake on someone's part.  It shouldn't be legal
to construct a view of an implicitly created temporary.  Or at
least not to escape it.

As a more straightforward example of the same problem, I ran into
a similar issue when creating constructor functions for a slice
class I use for my own work.  Those functions can't accept a
const ref to a std::string, because you can end up with this:

slice<char const> wrap(std::string const &s) {
      return slice<char const>(s.c_str(), s.length());
}

slice<char const> s = wrap("abc"); // s now aliases a discarded
temporary

I had to choose my overloads very carefully to avoid these issues.

In short, these problems crop up the moment you start aliasing
objects in C++.  To be honest, I'm amazed that the STL contains
something like string_view.  What kind of guarantees is it
supposed to provide?


More information about the Digitalmars-d mailing list