Является ли это действительной функцией?
Что происходит с ссылкой в функциональном параметре, если он будет уничтожен при возврате функции, то как const int *i
все еще является допустимым указателем?
const int* func(const int &x = 5)
{
return &x;
}
int main()
{
const int *i = func();
}
Ответы
Ответ 1
§12.2/5:
"Временная привязка к эталонному параметру в вызове функции (5.2.2) сохраняется до завершения полного выражения, содержащего вызов."
Это означает, что при инициализации i
он получает адрес временного объекта, который существует в этой точке. Однако, как только i
инициализируется, временный объект будет уничтожен, а i
станет еще одним висячим указателем.
Таким образом, да, функция действительна - но с окружающим кодом, как вы его написали, любой код, добавленный после этого, который пытался разыменовать i
, дал бы поведение undefined.
Ответ 2
Просто потому, что указатель имеет значение, это не значит, что он действительный указатель.
В этом случае он содержит адрес, который раньше был адресом x, и вероятность того, что адрес все еще имеет значение 5, но не является допустимым указателем, и вы не можете рассчитывать на то, что оно есть.
Ответ 3
int i
указывает на патч памяти, который небезопасен для доступа, он не является допустимым указателем.
Ответ 4
переменная "i" по-прежнему является указателем, но даже чтение значения, которое оно указывает, даст вам поведение undefined. Вот почему вы никогда не должны писать функцию func.
Ответ 5
Я думаю, что x
создается как неименованный временной в стеке при настройке вызова на func()
. Это временное существо будет существовать, по крайней мере, до конца оператора в вызывающем. Таким образом, int* i
отлично действует. Он только перестает быть действительным в конце инструкции - это означает, что вы не можете его использовать.
Есть что-то в стандарте о неименованных временных записях, которые сохраняются до тех пор, пока последняя ссылка на них не выйдет из области видимости, но я не думаю, что она охватывает эту явную и скрытую косвенность.
[Рад, что кто-то сказал мне об этом.]
Ответ 6
5 - это программные данные. Он находится в сегменте данных, а не в стеке или куче.
Таким образом, указатель или ссылка на него останутся действительными в течение всего времени программы.
Ответ 7
Аргументы по умолчанию оцениваются каждый раз при вызове функции, поэтому вызов func()
на самом деле func(5)
, который привязывает временную ссылку на const. Время жизни этого временного объекта затем расширяется до конца функции, и объект уничтожается. Любой указатель на этот объект после этого недействителен и разыменовывает его как поведение undefined.