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

Is it safe to store string literals pointers?

根据标准:

5.13.5 String literals [lex.string]

16 Evaluating a string-literal results in a string literal object with static storage duration, initialized from the given characters as specified above. Whether all string literals are distinct (that is, are stored in nonoverlapping objects) and whether successive evaluations of a string-literal yield the same or a different object is unspecified.

和:

6.6.4.1 Static storage duration [basic.stc.static]

1 All variables which do not have dynamic storage duration, do not have thread storage duration, and are not local have static storage duration. The storage for these entities shall last for the duration of the program

我认为存储指向字符串文字的指针是安全的,例如:

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")
    {
    }
};

上面的代码定义好了吗?是否有任何我必须注意的标准暗角?

Is the above code well defined?

是的。

Are there any dark corners of standard that I have to be aware of?

也许不是标准中的一个黑暗角落,但一个问题是你有一个指针并且你允许 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
}