为什么gcc在返回指向局部变量的指针时抛出警告而不是在返回局部变量时抛出警告?

请参阅下面的代码示例。 函数fun_ret_loc_ptr()的语句return (&i)返回一个警告:“函数返回局部变量的地址”。 另一方面,语句return a函数fun_ret_loc_var()不会这样做。

 #include  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()到一个内存位置,该内存位置是与函数fun_ret_loc_ptr()对应的堆栈帧的一部分。 一旦此函数返回,堆栈帧(激活记录)将被销毁。 同样的事情应该适用于函数fun_ret_loc_var()的变量’a’( return a; fun_ret_loc_var() 。 即使它被返回,当它在main中使用时,对应于’a’的内存也会死亡。

从“ return ”声明的function角度来看,为什么会出现这种差异?

按值返回变量会复制它,因此从函数返回后使用它是安全的。

将引用(或指针)返回到局部变量是不安全的(因为从函数返回后引用/指针不再有效)。

现在 ,如果程序看起来像你期望的那样,那就是纯粹的巧合。 这称为未定义行为 。 事实上,结果可能是任何事情(从你的车开始到未来三周仔细制作午餐。这是未定义的

你在post的最后很好地介绍了解释。 你唯一的“错误”就是在函数调用结束时变量“死”。 确实它确实死了,但是返回了a的副本,而不是函数堆栈中的a。 因此,访问该函数的返回值没有问题。

您可以想象通过值或引用传递参数的类比。

在这里,您可以通过引用或值返回值。 如果按值返回值,则该值在调用者中可用。 如果通过引用返回值,则将值的引用返回给调用者。 要访问该值,调用者必须取消引用,但引用不再指向任何有效值。

函数不返回变量; 他们返回价值观 。 值是否来自局部变量是无关紧要的; 即使它没有,它来自一个“本地表达”(我的术语),其寿命甚至比局部变量的短。 返回指向本地(假​​设它是自动的,非静态的)变量的指针的问题是指针的无效,并且在函数返回后对它的任何使用都会导致未定义的行为。