我正在使用GCC编译器的代码块。在下面的代码中,编译器在返回本地引用时发出警告但在返回本地指针时没有警告,尽管两者都是相同的。为什么?
我理解这些变量是本地变量,一旦控制从函数返回就会被销毁。取消引用这些将导致未定义的行为。
int *check(int j)
{
int *q;
q= &j;
return q; // No warning
//return &j; // Warning
}
答案 0 :(得分:2)
首先,因为警告是可选的。
其次,这段代码
int *q
...
return q;
不直接返回局部变量的地址。您编写了显式代码,使指针指向一个在函数返回时变为无效的地址。没有编译器可以从中拯救你。
答案 1 :(得分:1)
-Wno回本地-ADDR 在函数返回后,不要警告将指针(或C ++,引用)返回到超出范围的变量。
编辑:我编辑了我早先的说法。原来GCC确实令我失望。显然,只有在您直接返回将从堆栈中清除的内容时,该错误才有效。如果你将它存储在一个临时变量中,GCC不会检查它,即使它有足够的信息来执行此操作,只需检查指针是否指向%EBP
和%ESP
之间的某个地址
以下是我为测试它而做的一些代码,以确认GCC不会检查。如果使用-Wall
运行它,则不会产生错误,但是如果返回&val
,它将产生两个警告(一个用于返回一个j未被使用)。我觉得GCC应该递归检查我的返回指针是否保持在范围内而不是检查立即值。
#include <stdio.h>
#include <stdlib.h>
int * myFunc(int val){
int *j;
j=&val;
return j; //Should not work val goes out of scope
}
int someFuncToClearMyStack(int a, int b, int c){
int d;
int e;
d=a+b+c;
e=c-b-a;
d=d-e;
return d;
}
int main(){
int *i;
int j;
i=myFunc(10);
printf("%i\n",*i);
j=someFuncToClearMyStack(3,4,5);
printf("%i %i",*i,j);
return 0;
}