Quick setup: I want to pass strings around in my program as a pointer and a size. I have a String class and a user-defined literal for constructing literal Strings:
struct String { const char *ptr; size_t sz; };
inline constexpr String operator "" _string(const char *s, size_t sz) {
return {s, sz};
}
int main() {
auto s = "hello"_string;
s.ptr[0]; //<-- is this access guaranteed to work?
}
Does the standard specify that the argument passed to my user-defined literal operator has static duration? i.e. is the above code actually equivalent to writing:
int main() {
String s{"hello", 5};
}
or is the compiler/linker allowed to leave me with a dangling pointer when I use the user-defined literal?
(Section 2.13.8 of N4527 did not seem to say anything on the subject of storage class of the argument to the user-defined string literal operators. Any pointers into the appropriate section(s) of the standard would be appreciated.)
The characters of a literal string are stored in order at contiguous memory locations. An escape sequence (such as \\ or \") within a string literal counts as a single character. A null character (represented by the \0 escape sequence) is automatically appended to, and marks the end of, each string literal.
String literals are stored in C as an array of chars, terminted by a null byte. A null byte is a char having a value of exactly zero, noted as '\0'.
String literals are convertible and assignable to non-const char* or wchar_t* in order to be compatible with C, where string literals are of types char[N] and wchar_t[N]. Such implicit conversion is deprecated.
Size of string literals In versions of Visual Studio before Visual Studio 2022 version 17.0, the maximum length of a string literal is 65,535 bytes. This limit applies to both narrow string literals and wide string literals.
From [lex.ext]:
If L is a user-defined-string-literal, let str be the literal without its ud-suffix and let len be the number of code units in str (i.e., its length excluding the terminating null character). The literal
L
is treated as a call of the form:operator "" X (str , len )
From [lex.string]:
Evaluating a string-literal results in a string literal object with static storage duration, initialized from the given characters as specified above.
So:
"hello"_string;
is equivalent to:
operator "" _string("hello", 5)
As "hello"
is a string-literal, it has static storage duration, so you will have no dangling pointer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With