开发者

What are the scenarios that cause the compiler to emit spurious warnings? [closed]

开发者 https://www.devze.com 2023-03-16 22:07 出处:网络
开发者_C百科 As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references,or expertise, but this question will likely solic
开发者_C百科 As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance. Closed 11 years ago.

I sometimes read such comment by previous developers inside the source code:

// and this is to make compiler stop crying

I think with C/C++ it's typical that something you are doing practically legal, but still compiler sees it as illegal.

Is there a list of the scenarios that cause the compiler to emit spurious warnings?


The most obvious example that springs to my mind is that gcc warns for this:

while (i = somefunc())

And you suppress the warning with a particular easter-egg:

while ((i = somefunc()))

Assuming of course that the warning is incorrect, and that you didn't mean to write:

while (i == somefunc())

But it's highly dependent on your coding style what warnings you will trigger in error-free code. Some people, admittedly a small proportion of C programmers, would never make an assignment in a conditional in the first place, so for them this warning is not "spurious", because if they get it then it's always because of a typo for ==.


One of the cases where a programmer might write such a comment is where the problem that the compiler has identified is actually impossible, but it lies beyond the power of the compiler to determine that fact. An example:

int foo(char *barArg) {
    char *barPtr, *grillPtr;
    if (barArg == NULL) {
        grillPtr = malloc(...);      /* allocate */
        get_default_bar(grillPtr);   /* initialize */
        barPtr = grillPtr;
    } else {
        barPtr = barArg;
    }

    /* Some common block of processing that does _not_ refer to grillPtr,
     * does _not_ assign to barArg, and _updates_ barPtr. */

    if (barArg == NULL) {
        free(grillPtr);              /* <<<----- here */
    }
    return 0;
}

In this case, it's entirely possible that the compiler will issue a warning about a potentially-uninitialized variable (grillPtr) for the line with a free() because it can't work out that it could only have got there if the allocation/initialization had happened.

While a smarter compiler could understand the flow graph more completely and determine that the code was in fact safe, programmers are more likely to make things shut up by just setting grillPtr to NULL at the top of the function, so doing a very little extra work to achieve a warning-free build. (There are other ways to achieve the same effect, but it's easier to get it right at the point of declaration of the variable.)

In reality, it's arguably the case that this is indicating that some refactoring should be done instead, so that the function core is separated from all the hokey setup/cleanup code (and called from two branches, one which allocates, the other which lacks the variable). Alas, that's not always that easy to arrange in practice.


There is no definitive list of such warnings, because the C standard does not disallow a conforming compiler from emitting warnings or diagnostic messages for legal code. Each C compiler therefore has its own list of warnings, some of which can trigger on perfectly correct, perfectly legal code (the canonical example of this is a function with an argument that is never used).

This means that code change to suppress such warnings are usually aimed at a specific compiler (and perhaps even a specific version of that compiler) - and often discovered by trial-and-error rather than anticipated in advance.

Sometimes, however, such a code modification is actually making the code correct - the compiler diagnostic being suppressed is one required by the C standard. The usual example of this is a cast required in an assignment - for example, an integer value cannot be assigned to a pointer object, but most compilers will emit a warning and compile the code anyway. Adding a cast in this case silences the warning because it corrects the code - the warning is not really spurious at all.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号