简体   繁体   中英

Why do I get a warning when using an int variable but not when using an integer constant?

I have two versions of a piece of code. The first is by using an int variable as part of an expression for a condition test, the second by using an integer constant for the same - both represent the same integral value - 24 .

1. code :

#include <stdio.h>

int main()
{
    int var = 24;

    if((!var) == NULL)
    {
        printf("1");
    }
}

2. code :

#include <stdio.h>

int main()
{
    if((!24) == NULL)
    {
        printf("1");
    }
}

When I attempt to compile the first version, I get the warning:

warning: comparison between pointer and integer

from gcc, and

warning: comparison between pointer and integer ('int' and 'void *') [-Wpointer-integer-compare]

from clang.

When I compile the almost equivalent code by using the same value just as integer constant, everything is fine. Why?


My research so far:

I looked into C18 and found on section 6.4.4 "Constants":

First under Subsection /2 and /3:

" 2 - Each constant shall have a type and the value of a constant shall be in the range of representable values for its type. "

" 3 - Each constant has a type, determined by its form and value, as detailed later. ".

And second under Subsection /5:

" The type of an integer constant is the first of the corresponding list in which its value can be represented. "

The following list:

列表

Thus, an integer constant with no suffix and relative to the representable value of 24 should have type int .


I understand the warning itself and know that NULL usually on most implementations expands to (void*) 0 . Thus, it is reasonable that this warning is thrown.

But why does the warning not occur when using the same value as integer constant?

From C11 6.3.2.3/3:

An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.

And from 6.5.9/2 regarding equality operators == and != :

One of the following shall hold:
...
— one operand is a pointer and the other is a null pointer constant.

Note that integer constant expressions are not limited to integer constants (0, 42, etc.) but can also include operators acting on them like 5+5-10 .

!24 is an integer constant expression with the value 0, and therefore counts as a null pointer constant. The == operator is allowed to act between a pointer and a null pointer constant, which makes (!24) == NULL a valid comparison.

In your first example, !var is not an integer constant expression because it includes a variable operand, and thus cannot be compared with a pointer.

Caveat: In most implementations, NULL is defined as (void*)0 and the above is correct. However, the standard allows it to be defined it as any null pointer constant such as 0 . If this is the case, then the comparison (!var) == NULL will compile because it is the same as (!var) == 0 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM