在 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。
考虑以下代码:
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。