When checking
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char c[20];
size_t l;
l = fread(c, sizeof c, 1, stdin);
if (l != 1)
return 1;
return c[0] == 42;
}
with clang, I get
$ clang --analyze -Xclang -analyzer-checker=alpha x.c
x.c:13:14: warning: The left operand of '==' is a garbage value
return c[0] == 42;
~~~~ ^
$ clang -v
clang version 7.0.1 (Fedora 7.0.1-4.fc29)
Is there really a chance that c
contains garbage at this point? If not, how can I avoid the warning (without the obvious initialization of c
)?
Update
Because it seems to be common consensus, that this is a false positive, I want to focus on the way how to avoid the warning.
It is true that fread()
is a standard function and analyzers should know their semantics as they are doing e.g. for memset()
already. But I am interested in a more generic way which can be used e.g. on library functions.
I would call some special function (let call it assert_defined()
) in a way like
l = fread(c, sizeof c, 1, stdin);
assert_defined(c, l * sizeof c);
which is
- a noop
- but lets the compiler/analyzer think that
l * sizeof c
bytes atc
are initialized
Does clang know annotations like
inline static void assert_defined(void const *p, size_t cnt)
__attribute__((__dear_compiler_this_memory_is_not_garbage__(1,2)))
{
}
or are there tricks like the related
int i = i;
which prevents gcc to emit "uninitialized warnings"?