How to make gcc warn about returning the address of local variables?

霸气de小男生 提交于 2019-11-27 23:40:41

问题


With gcc 4.4.5, I have a warning with the following code.

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

But, when I use a temporary pointer, there is no warning anymore (even if the behavior is wrong).

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

I heard that pointer-analysis is difficult in C, but can gcc warn about such code ?


回答1:


Compilers, and most static analyzers, do not try to warn for everything wrong a program might do, because that would entail too many false positives (warnings that do not correspond to actual problems in the source code).

Macmade recommends Clang in the comments, a recommendation I can second. Note that Clang still aims at being useful for most developers by minimizing false positives. This means that it has false negatives, or, in other words, that it misses some real issues (when unsure that there is a problem, it may remains silent rather than risk wasting the developer's time with a false positive).


Note that it is even arguable whether there really is a problem in function f() in your program. Function h() below is clearly fine, although the calling code mustn't use p after it returns:

char *p;

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

Another static analyzer I can recommend is Frama-C's value analysis (I am one of the developers). This one does not leave any false negatives, for some families of errors (including dangling pointers), when used in controlled conditions.

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
... 

The above are only informative messages, they do not mean the function is necessarily wrong. There is one for my function h() too:

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

The real error, characterized by the word “assert” in Frama-C's output, is if a function calls h() and then uses 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>).

Frama-C's value analysis is called context-sensitive. It analyses function h() for each call, with the values that are actually passed to it. It also analyzes the code that comes after the call to h() in function caller() with the values that can actually be returned by h(). This is more expensive than the context-insensitive analyses that Clang or GCC typically do, but more precise.




回答2:


In this first example, gcc can clearly see you're returning the address of an automatic variable that will no longer exist. In the second, the compiler would have to follow your program's logic, as p could easily point to something valid (e.g. an external character variable).

Although gcc won't complain here, it will warn with pointer use like this:

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

Again, it can see without any doubt that you're removing the 'const' qualifier in this definition.

Another utility that will detect this problem is splint (http://splint.org).



来源:https://stackoverflow.com/questions/12228731/how-to-make-gcc-warn-about-returning-the-address-of-local-variables

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!