C 编译器不会在返回本地指针时发出警告

C 编译器不会在返回本地指针时发出警告,c,C,我正在使用GCC编译器的代码块。在下面的代码中,编译器在返回本地引用时发出警告,但在返回本地指针时不发出警告,尽管两者是相同的。为什么? 我知道这些变量是局部变量,一旦控件从函数返回,它们就会被销毁。取消引用这些将导致未定义的行为 int *check(int j) { int *q; q= &j; return q; // No warning //return &j; // Warning } 首先,因为警告是可选的 第二,这个代码 int

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

我知道这些变量是局部变量,一旦控件从函数返回,它们就会被销毁。取消引用这些将导致未定义的行为

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

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

首先,因为警告是可选的

第二,这个代码

int *q
...
return q;

不直接返回局部变量的地址。您编写了显式代码,使指针指向一个在函数返回时变为无效的地址。没有一个编译器可以帮你避免这种情况。

安德鲁,我不同意。 据

-Wno返回本地地址 不要警告将指针(或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;
}
#包括
#包括
int*myFunc(int-val){
int*j;
j=&val;
return j;//不应工作val超出范围
}
int someFunctionClearMyStack(int a、int b、int c){
int d;
INTE;
d=a+b+c;
e=c-b-a;
d=d-e;
返回d;
}
int main(){
int*i;
int j;
i=myFunc(10);
printf(“%i\n”,*i);
j=someFunctionClearMyStack(3,4,5);
printf(“%i%i”,*i,j);
返回0;
}

如果不使用返回值,程序将保持定义状态。编译器帮了你一个忙,警告你,它不必这样做。无法复制,我安装的gcc(5.4.0)会产生预期的警告。因为编译器不够聪明。你不应该指望编译器足够聪明。只要你不使用返回值来访问指向的内存地址,就不会造成任何伤害。请看下面我的答案。它没有显示如何获得警告,但它显示了一个有趣的问题,我想说的是GCC。好的,我现在知道了。编译器不检查指针指向的位置,因此没有警告。但它在返回引用时会看到地址。