Продолжительность хранения базовых символьных данных с пользовательским строковым литералом
Быстрая настройка: я хочу передать строки в моей программе в виде указателя и размера. У меня есть класс String и пользовательский литерал для построения литеральных строк:
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?
}
Указывает ли стандарт, что аргумент, передаваемый моему пользовательскому литеральному оператору, имеет статическую длительность? т.е. приведенный выше код фактически эквивалентен написанию:
int main() {
String s{"hello", 5};
}
или компилятору / компоновщику разрешено оставлять меня с висящим указателем, когда я использую пользовательский литерал?
(В разделе 2.13.8 N4527, похоже, ничего не сказано о предмете класса хранения аргумента для пользовательских строковых литеральных операторов. Любые указатели на соответствующие разделы стандарта будут приветствоваться.)
1 ответ
Из [lex.ext]:
Если L является определяемым пользователем строковым литералом, пусть str будет литералом без его ud-суффикса, и пусть len будет количеством единиц кода в str (т. Е. Его длиной, исключая завершающий нулевой символ). Буквальный
L
трактуется как вызов формы:operator "" X (str , len )
Из [lex.string]:
Оценка строкового литерала приводит к получению строкового литерала со статической продолжительностью хранения, инициализированного из заданных символов, как указано выше.
Так:
"hello"_string;
эквивалентно:
operator "" _string("hello", 5)
Как "hello"
является строковым литералом, имеет статическую длительность хранения, поэтому у вас не будет висящего указателя.