如何使海湾合作委员会警告返回局部变量的地址?(How to make gcc warn about

2019-06-27 16:38发布

随着gcc 4.4.5,我有下面的代码警告。

char *f(void)
{
    char c;
    return &c;
}

但是,当我使用一个临时指针,没有警告了(即使该行为是错误的)。

char *f(void)
{
    char c;
    char *p = &c;
    return p;
}

听说指针分析很难在C,但可以gcc警告这样的代码?

Answer 1:

编译器和大多数静态分析仪,不要试图警告的一切错误的程序可能会做,因为这将带来太多的误报(警告,不符合实际的问题在源代码中)。

Macmade建议锵的意见,建议我可以秒。 需要注意的是锵仍旨在通过最大限度地减少误报是对于大多数开发人员非常有用。 这意味着它有假阴性或者,换句话说,它错过了一些实际问题(不能确定时,有一个问题,它可能不是风险浪费开发者的时间有假阳性保持沉默)。


需要注意的是,即使有争议是否真的是在功能上有问题f()在你的程序。 函数h()下面是清晰细腻,虽然调用的代码不能使用p返回之后:

char *p;

void h(void)
{
    char c;
    p = &c;
}

另一种静态的分析,我可以推荐是邮资-C的价值分析 (我的开发者之一)。 这一个不留任何漏报,错误的一些家庭(包括悬摆指针),在受控条件下使用时。

char *f(void)
{
    char c;
    return &c;
}

char *g(void)
{
    char c;
    char *p = &c;
    return p;
}

$ frama-c -val -lib-entry -main g r.c
...
r.c:11:[value] warning: locals {c} escaping the scope of g through \result
...
$ frama-c -val -lib-entry -main f r.c
...
r.c:4:[value] warning: locals {c} escaping the scope of f through \result
... 

以上只是信息的消息,他们并不意味着功能必然是错误的。 有一个我的函数h()太:

h.c:7:[value] warning: locals {c} escaping the scope of h through p

真正的错误,其特征在于在邮资-C的输出词语“断言”,如果是一个函数调用h()然后使用p

void caller(void)
{
  char d;
  h();
  d = *p;
}

$ frama-c -val -lib-entry -main caller h.c
...
h.c:7:[value] warning: locals {c} escaping the scope of h through p
...
h.c:13:[kernel] warning: accessing left-value p that contains escaping addresses; assert(Ook)
h.c:13:[kernel] warning: completely undefined value in {{ p -> {0} }} (size:<32>).

邮资-C的价值分析被称为上下文敏感 。 它分析函数h()的每个调用,与实际传递给它的值。 报告还分析了呼叫后到来代码h()函数caller()与实际上可以通过返回的值h() 这是比上下文不敏感分析了锵或GCC通常做更昂贵,但更精确。



Answer 2:

在第一个例子,GCC可以清楚地看到你回来的自动变量将不再存在的地址。 在第二,编译器必须遵循你的程序的逻辑,为p可以很容易地指向有效的东西(如外部字符变量)。

虽然GCC不会抱怨这里,它将与指针使用这样的警告:

char *f(const char *x)
{
  char *y = x;
  ...
}

再次,它可以看到没有,你在这个定义中删除“const”限定符任何怀疑。

将检测到这个问题的另一个工具是夹板(http://splint.org)。



文章来源: How to make gcc warn about returning the address of local variables?