编译器在返回本地指针

时间:2016-07-13 17:05:09

标签: c

我正在使用GCC编译器的代码块。在下面的代码中,编译器在返回本地引用时发出警告但在返回本地指针时没有警告,尽管两者都是相同的。为什么?

我理解这些变量是本地变量,一旦控制从函数返回就会被销毁。取消引用这些将导致未定义的行为。

int *check(int j)
{
    int *q;

    q= &j;
    return q; // No warning
    //return &j; // Warning
}

2 个答案:

答案 0 :(得分:2)

首先,因为警告是可选的。

其次,这段代码

int *q
...
return q;

不直接返回局部变量的地址。您编写了显式代码,使指针指向一个在函数返回时变为无效的地址。没有编译器可以从中拯救你。

答案 1 :(得分:1)

安德鲁我不得不反对。 根据{{​​3}}

  

-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;
}