It's simply because the compilers are not smart enough to do it. It would be possible to make them so smart, but most likely, the compiler constructors simply does not think it's worth the effort. Because in the end, writing correct code is the programmers responsibility.
In fact, they are so smart. As OznOg mentioned below in comments, the optimizer is using things like this to make the code faster. But the standard does not require a compiler to issue a warning for this, and C has a mentality that has a very strong focus on the programmer. It simply does not hold your hand like Java does.
Furthermore, warnings of that kind would easily generate a lot of false positives. In your code it's fairly trivial, but one can easily imagine more complex examples with branches. Like this code:
int *q = malloc(*q);
int *p = 0;
if(n%2 == 0) p = q;
*p = 42;
On the last line we will write to NULL
if n
is odd and to q
if n
is even. And q
is a valid address. Well, provided that malloc
succeeded. Should this also generate a warning?
There is a compiler option for gcc
and possibly others that gives you this. However, it's not required by the standard. And the reason for not being enabled by default is basically the same as to why the standard does not require it.
And in this situation, the correct way of handling it would be that YOU add a null check in the function. Like this:
void isEven (int *isFlag, int num) {
if(!isFlag) {
/* Handle error. Maybe error message and/or exit */
} else if (num % 2 == 0) {
*isFlag = 1;
} else {
*isFlag = 0;
}
}
C compilers usually don't remember values. For instance, this generates the warning warning: division by zero
:
int y = 1/0;
but not this:
int x = 0;
int y = 1/x;
One way to detect these errors is to compile with --fsanitize=address
. You will not discover it during compile time, but during runtime.