Given the code
// somewhere in the program
const char* p1 = \"Hello World\";
// somewhere else in the program
const char* p2 = \"Hello World\";
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>
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();
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).
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.