1

So, I was reading about using enum as part of the new C++2a standards here and came across the following code:

enum class rgba_color_channel { red, green, blue, alpha};

std::string_view to_string(rgba_color_channel channel) {
  switch (my_channel) {
    using enum rgba_color_channel;
    case red:   return "red";
    case green: return "green";
    case blue:  return "blue";
    case alpha: return "alpha";
  }
}

This got me to wonder how returning a std::string_view works? To my mind "red", "green", ... are temporary variables and the thus should not work, so I wrote some test code:

std::string_view to_red() {
    return "red";
}

std::string_view to_green() {
    const char* green{ "green" };
    return green;
}

std::string_view to_blue() {
    std::string blue{ "blue" };
    return blue;
}

std::string_view to_alpha() {
    std::string alpha{ "alpha" };
    return std::string_view(alpha);
}


int main()
{
    std::cout << "red: " << to_red() << "\n";
    std::cout << "green: " << to_green() << "\n";
    std::cout << "blue: " << to_blue() << "\n";
    std::cout << "alpha: " << to_alpha() << "\n";
}

Output:

red: red
green: green
blue: ╠╠╠╠
alpha: ╠╠╠╠╠

Blue and alpha behaved as I expected (undefined behavior), however red and green did not. So, my question is why does const char* seem to work? Or is this just a msvc manifestation of undefined behavior?

davidbear
  • 375
  • 2
  • 13

1 Answers1

3

To my mind "red", "green", ... are temporary variables and the thus should not work

No. String literals have static storage duration and thus exist in memory for the life of the program.

how returning a std::string_view works?

Well, it constructs the string_view from a string literal. string_view stores the pointer to the string literal, so it is valid as long as string literal is valid. As string literal is valid for the life of the program, the string_view is also valid.

my question is why does const char* seem to work?

Because const char* pointer points to a string literal.

std::string_view func() { 
    return "this is a string literal";
    const char *also_a_string_literal = "another string literal";
    const char not_a_string_literal_on_stack[] = "text";
    std::string constructed_using_dynamic_allocation("or not, it depends");
}

Or is this just a msvc manifestation of undefined behavior?

No.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • The `static storage duration` is what I didn't understand. Thanks – davidbear Feb 09 '20 at 20:54
  • If you looked in the object code of your program, you will find the string literals embedded in it (usually in special text section). As these are part of the program that is loaded into memory in order to execute they have fixed addresses that can be used. – Ian4264 Feb 09 '20 at 21:43