问题描述
按照标准:
5.13.5 字符串文字 [lex.string]
16 对字符串字面量求值会产生一个具有静态存储持续时间的字符串字面量对象,从上面指定的给定字符初始化。是否所有字符串文字都是不同的(即存储在不重叠的对象中)以及字符串文字的连续计算是否产生相同或不同的对象是未指定的。
和:
6.6.4.1 静态存储时长 [basic.stc.static]
1 所有没有动态存储期、没有线程存储期、非局部变量都有静态存储期。这些实体的存储将在程序期间持续
我认为存储指向字符串文字的指针是安全的,例如:
struct Base
{
Base(const char* name)
: _name(name)
{
}
void print()
{
std::cout<<_name<<std::endl;
}
const char* _name = nullptr;
};
struct MyDerived : public Base
{
MyDerived () : Base("MyDerived")
{
}
};
上面的代码定义好了吗?标准中是否有任何我必须注意的暗角?
解决方法
上面的代码定义好了吗?
是的。
是否有任何标准的暗角需要我注意?
也许不是标准中的黑暗角落,但一个问题是您有一个指针,并且您允许 Base
像这样被实例化和使用:
Base foo(nullptr);
foo.print();
来自operator<<
:
"如果 s
是空指针,则行为未定义。"
更安全的构造函数:
template<size_t N>
constexpr Base(const char(&name)[N]) : _name(name) {}
我说有点是因为你仍然可以这样做:
auto Foo() {
const char scoped[] = "Fragile";
Base foo(scoped);
foo.print(); // OK
return foo;
} // "scoped" goes out of scope,"_name" is now dangling
int main() {
auto f = Foo();
f.print(); // UB
}