Почему возвращает ссылку на строковый литерал ссылку на временную?

Строковый литерал строковой строки имеет следующее определение:

Также указываются обычные строковые литералы и строковые литералы 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";

Здесь переменная создается в стеке... и эта переменная (которая является указателем) указывает на ячейку памяти, в которой хранится строковый литерал. Вы не возвращаете сам строковый литерал; вы скорее вернете ссылку на переменную, которая вскоре будет уничтожена в результате разворачивания стека. Следовательно, возвращение ссылки на такую ​​переменную опасно, поскольку это временный объект.