在 constexpr 函数中返回 C 字符串:为什么没有来自编译器的警告?

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

考虑以下代码:

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;
}

我的编译器不显示任何警告是否正常?它是定义的行为吗?我能保证程序会显示 "Hello World!" 吗?我希望 "Hello World!" 不会超出函数的范围...

在 C++ 中 string literals have static storage duration 并且只要程序运行就一直存在。因此,指向从 f 返回的字符串文字的指针始终有效。不涉及分配或解除分配。

请注意,字符串文字的类型为 const char[N],在您的情况下,由于 auto 类型推导,它会衰减为 const char *。如果你的意图是使用std::string,你可以直接构造它

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

或使用operator""s:

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

但是,由于 std::string 不是字面量类型,因此它的值不再是 cannot be constexpr

这是自动的第二个效果。您认为的并不总是编译器决定的。这可能会导致错误的程序员期望 - 规则在这里 编译器总是赢

这里的事实是 str 是一个 const char * 到(静态存储持续时间)字符串乱码。它可以在构建时完全确定,因此它是一个有效的constexpr。