【问题标题】:The compiler gives no warning on returning local pointer编译器在返回本地指针时没有给出警告
【发布时间】:2016-07-13 17:05:08
【问题描述】:

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

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

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

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

【问题讨论】:

  • 如果您不使用返回值,程序将保持定义。编译器通过警告您来帮您一个忙,它不必这样做。
  • 无法重现,我安装的 gcc (5.4.0) 产生了预期的警告。
  • 因为编译器不够聪明。你不应该依赖编译器足够聪明。
  • 只要你不使用返回值来访问指向的内存地址,就没有坏处。
  • 请看下面我的回答。它没有显示如何获得警告,但它显示了一个有趣的我想说的 GCC 问题。

标签: c


【解决方案1】:

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

二、这段代码

int *q
...
return q;

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

【讨论】:

  • 好的,我现在知道了。编译器不检查指针指向的位置,因此没有警告。但是它在返回引用时会看到地址。
【解决方案2】:

安德鲁我不得不不同意。 根据gcc documentation

-Wno-return-local-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;
}

【讨论】:

    猜你喜欢
    • 2011-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多