存储字符串字面量指针是否安全?

5
根据标准规定:
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")
    {
    }
};

以上的代码是否定义良好?有任何我需要注意的标准中的难点吗?


2
是的,它是明确定义和安全的。只要确保您不尝试修改字符或释放指向的内存即可。 - Remy Lebeau
1
不要假设在 const char* x = "abcd"; const char* y = "abcd"; 之后,x == y 将会是真的。 - Pete Becker
1个回答

4
上面的代码是否定义良好? 是的。
标准中有任何我需要注意的黑暗角落吗? 或许不是标准中的黑暗角落,但一个问题是你有一个指针,并且允许像这样实例化和使用“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
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接