Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to pass an `std::string` temporary into an `std::string_view` parameter?

Suppose I have the following code:

void some_function(std::string_view view) {
    std::cout << view << '\n';
}

int main() {
    some_function(std::string{"hello, world"}); // ???
}

Will view inside some_function be referring to a string which has been destroyed? I'm confused because, considering this code:

std::string_view view(std::string{"hello, world"});

Produces the warning (from clang++):

warning: object backing the pointer will be destroyed at the end of the full-expression [-Wdangling-gsl]

What's the difference?

(Strangely enough, using braces {} rather than brackets () to initialise the string_view above eliminates the warning. I've no idea why that is either.)

To be clear, I understand the above warning (the string_view outlives the string, so it holds a dangling pointer). What I'm asking is why passing a string into some_function doesn't produce the same warning.

like image 911
bewilderex63 Avatar asked Jul 18 '26 07:07

bewilderex63


2 Answers

some_function(std::string{"hello, world"}); is completely safe, as long as the function doesn't preserve the string_view for later use.

The temporary std::string is destroyed at the end of this full-expression (roughly speaking, at this ;), so it's destroyed after the function returns.


std::string_view view(std::string{"hello, world"}); always produces a dangling string_view, regardless of whether you use () or {}. If the choice of brackets affects compiler warnings, it's a compiler defect.

like image 76
HolyBlackCat Avatar answered Jul 19 '26 22:07

HolyBlackCat


std::string_view is nothing other than std::basic_string_view<char>, so let's see it's documentation on cppreference:

The class template basic_string_view describes an object that can refer to a constant contiguous sequence of char-like objects with the first element of the sequence at position zero.

A typical implementation holds only two members: a pointer to constant CharT and a size.

The part I have highlighted tells us why clang is right about std::string_view view(std::string{"hello, world"});: as others have commented it's because after the declaration is done, std::string{"hello, world"} is destroyed and that underlying pointer that the std::string_view holds dangles.

Clearly that's just a typical implementation, but since we know it is correct, it tells us at least that the standard doesn't require any implementation to do something special to keep temporaries alive.

like image 44
Enlico Avatar answered Jul 19 '26 21:07

Enlico



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!