Returning a C string in a constexpr function: why no warning from the compiler?
Asked Answered
A

2

8

Consider the following code:

constexpr auto f()
{
    auto str = "Hello World!";
    return str;
}

int main(int argc, char* argv[])
{
    static constexpr auto str = f();
    std::cout << str << std::endl;
    return 0;
}

Is that normal that my compiler does not display any warning? Is it defined behavior? Do I have the guarantee that the program will display "Hello World!"? I would expect the "Hello World!" not to live beyond the scope of the function...

Ambulance answered 28/7, 2017 at 6:54 Comment(0)
A
14

In C++ string literals have static storage duration and live as long as the program runs. So, a pointer to a string literal returned from f is always valid. No allocation or deallocation is involved.

Note that string literals have type const char[N], which in your case decays to const char * due to auto type deduction. If your intent was to use std::string, you can directly construct it

auto str = std::string("Hello World!");

or use operator""s:

using std::string_literals;
auto str = "Hello World!"s;

However, since std::string is not a literal type, this values cannot be constexpr anymore.

Antiquarian answered 28/7, 2017 at 7:2 Comment(2)
"string literals have type const char *" They don't.Gritty
@Gritty const char array of concrete length?Strike
S
5

That's the second effect of auto. What you think it is, is not always what the compiler decides. This can leads to wrong programmer expectation - the rule is here compiler always win.

The fact here is that str is a const char * to a (static storage duration) string litteral. It can be fully determined at build time, so it is a valid constexpr.

Surfbird answered 28/7, 2017 at 7:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.