Почему возвращает ссылку на строковый литерал ссылку на временную?
Строковый литерал строковой строки имеет следующее определение:
Также указываются обычные строковые литералы и строковые литералы UTF-8 как узкие строковые литералы. Узкий строковый литерал имеет тип "массив" of n const char ", где n - размер строки, как определено ниже, и имеет статическую продолжительность хранения (3.7).
Я предполагаю, что он имеет статическую продолжительность хранения и что они, как правило, помещаются в ПЗУ, это действительно не имеет большого значения, если есть болтливая ссылка на него. Следующий код выдает предупреждение
const char* const & foo()
{
return "Hello";
}
// warning: returning reference to temporary [-Wreturn-local-addr]
Но это прекрасно, даже без статического ключевого слова
const char* const & foo()
{
const char* const & s = "Hello";
return s;
}
Так в чем же разница между этими двумя?
Ответы
Ответ 1
Цитата, которую вы указали, говорит, что
Узкий строковый литерал имеет тип "array of n const char"
То есть тип "Hello"
равен const char[6]
.
Ваш код возвращает ссылку на const char *
. Это означает, что преобразование массива в указатель должно быть применено к строковому литералу, что приводит к присвоению prvalue (= временному) типа const char *
. Затем вы привязываете это к ссылке и возвращаете эту ссылку. Ссылка становится болтающейся, как только заканчивается область действия функции, и временный указатель уничтожается.
Ответ 2
Нет никакой разницы. В обоих случаях вы возвращаете ссылку на указатель, который больше не существует.
То, что точка (данные) все еще существует навсегда, не имеет значения.
Ответ 3
const char* const & s = "Hello";
Здесь переменная создается в стеке... и эта переменная (которая является указателем) указывает на ячейку памяти, в которой хранится строковый литерал. Вы не возвращаете сам строковый литерал; вы скорее вернете ссылку на переменную, которая вскоре будет уничтожена в результате разворачивания стека. Следовательно, возвращение ссылки на такую переменную опасно, поскольку это временный объект.