Почему gcc выдает предупреждение при возврате указателя на локальную переменную, а не при возврате локальной переменной? - PullRequest
1 голос
/ 18 ноября 2011

Пожалуйста, посмотрите пример кода ниже.Оператор return (&i) в функции fun_ret_loc_ptr() возвращает предупреждение: «функция возвращает адрес локальной переменной».С другой стороны, оператор return a в функции fun_ret_loc_var() не делает этого.

#include <stdio.h>
int* fun_ret_loc_ptr()
{
   int i = 10;
   return (&i);
}

int fun_ret_loc_var()
{
   int a = 20;
   return a;
}

int main()
{
   printf("val frm local ptr = %d\n", *fun_ret_loc_ptr());
   printf("val frm local var = %d\n", fun_ret_loc_var());
}

Я понимаю, что в первой функции возвращенный адрес (return (&i);) ссылается на область памяти, котораябыл частью стекового фрейма, соответствующего функции fun_ret_loc_ptr().Как только эта функция вернула, стековый фрейм (запись активации) будет уничтожен.То же самое должно быть применимо к переменной 'a' (return a;) в функции fun_ret_loc_var().Даже если он возвращается, когда он используется в main, память, соответствующая 'a', умерла бы.

С точки зрения функциональности оператора "return", почему возникает это различие?

Ответы [ 4 ]

5 голосов
/ 18 ноября 2011

Возвращение переменной по значению копирует ее, и поэтому ее можно безопасно использовать после возврата из функции.

Возврат ссылки (или указателя) на локальную переменную небезопасен (поскольку ссылка / указатель больше не действительны после возврата из функции).

Теперь , если программа , казалось, делает то, что вы ожидаете, это чистое совпадение. Это известно как Неопределенное поведение . Фактически, результатом может быть что угодно (от взрыва автомобиля до тщательного приготовления обеда на ближайшие три недели подряд. Это просто undefined )

2 голосов
/ 18 ноября 2011

В конце своего поста вы довольно хорошо объяснили объяснение.Ваша единственная «ошибка» состоит в том, что переменная a «умирает» в конце вызова функции.Действительно, он умирает, но возвращается копия a, а не a из стека функций.Следовательно, нет проблем с доступом к возвращаемому значению этой функции.

1 голос
/ 18 ноября 2011

Можно привести аналогию с передачей аргументов по значению или по ссылке.

Здесь вы возвращаете значение по ссылке или по значению.Если вы возвращаете значение по значению, то это значение доступно в вызывающей стороне.Если вы возвращаете значение по ссылке, то ссылка на значение возвращается вызывающей стороне.Чтобы получить доступ к значению, вызывающая сторона должна разыменовать, но ссылка больше не указывает на какое-либо действительное значение.

0 голосов
/ 18 ноября 2011

Функции не возвращают переменные; они возвращают значения . Принято ли значение из локальной переменной, не имеет значения; даже если это не так, оно пришло из «локального выражения» (мой термин), время жизни которого даже короче, чем у локальной переменной. Проблема с возвратом указателя на локальную (при условии, что это автоматическая, а не статическая) переменная заключается в том, что значение указателя недопустимо, и любое его использование после возврата функции приводит к неопределенному поведению.

...