Ensure that char pointers always point to the same string literal

前端 未结 4 1130
攒了一身酷
攒了一身酷 2021-01-16 12:18

Given the code

// somewhere in the program
const char* p1 = \"Hello World\";

// somewhere else in the program
const char* p2 = \"Hello World\";
相关标签:
4条回答
  • 2021-01-16 12:54

    As Barry shows in their answer the behavior you want is not guaranteed. You're going to have to pay the cost of string comparisons, but you can at least avoid any memory allocations or writing a comparator by using a std::string_view. A std::string_view is a lightweight view of a string that holds a pointer to the string data and the size of the string and it has a built in operator < that will do a lexicographical comparison. That would change your map to

    std::map<std::string_view, something>
    
    0 讨论(0)
  • 2021-01-16 13:02

    There is no such requirement. [lex.string]/15:

    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.

    Best you can do is assert() or just avoid repeating yourself and stick the thing in a function:

    char const* my_literal() { return "Hello World"; }
    
    char const* p1 = my_literal();
    char const* p2 = my_literal();
    
    0 讨论(0)
  • 2021-01-16 13:08

    Identical literal strings are not guaranty to be identical, but as you use MACRO to create the string, you can change it to return identical string.

    gcc/clang have an extension to allow to build UDL from literal string:

    template<typename Char, Char... Cs>
    struct CsHelper
    {
        static constexpr const Char s[] = {Cs..., 0}; // The unique address
    };
    
    // That template uses the extension
    template<typename Char, Char... Cs>
    constexpr auto operator"" _cs() -> const Char (&)[1 + sizeof...(Cs)] {
        return CsHelper<Char, Cs...>::s;
    }
    

    and then

    #define nameof(id) #id ## _cs
    

    See my answer from String-interning at compiletime for profiling to have MAKE_STRING macro if you cannot used the extension (Really more verbose, and hard coded limit for accepted string length).

    0 讨论(0)
  • 2021-01-16 13:08

    There is no requirement that two string literals with the same text are the same object. So the two mentions of ”Hello world” may or may not refer to a single string in memory. That means that

    const char* p1 = "Hello World";
    const char* p2 = "Hello World";
    

    Does not necessarily make p1 equal to p2. To do that, you have to set one of them equal to the other:

    const char* p2 = p1;
    

    But either one of those pointers can be modified, and the other pointer won’t track that change. To make sure that such changes can’t be done, make the pointers const:

    const char* const p1 = "Hello World";
    const char* const p2 = p1;
    

    Or, if p1 needs to be modifiable, make p2 a reference:

    const char* p1 = "Hello World";
    const char*& p2 = p1;
    

    Now p2 will point at whatever p1 points at.

    0 讨论(0)
提交回复
热议问题