При проверке
#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;
}
с помощью clang я получаю
$ 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)
Действительно ли существует вероятность того, что c
содержит мусор в этот момент?Если нет, то как я могу избежать предупреждения (без явной инициализации c
)?
Обновление
Поскольку, как представляется, существует общее мнение, что это ложное срабатывание, я хочусосредоточиться на том, как избежать предупреждения.
Это правда, что fread()
является стандартной функцией, и анализаторы должны знать свою семантику так, как они это делают, например, для memset()
.Но меня интересует более общий способ, который можно использовать, например, в библиотечных функциях.
Я бы вызвал некоторую специальную функцию (пусть она будет вызываться assert_defined()
) таким образом, как
l = fread(c, sizeof c, 1, stdin);
assert_defined(c, l * sizeof c);
который является
- noop
- , но позволяет компилятору / анализатору думать, что
l * sizeof c
байтов в c
инициализированы
Знает ли лязганнотации типа
inline static void assert_defined(void const *p, size_t cnt)
__attribute__((__dear_compiler_this_memory_is_not_garbage__(1,2)))
{
}
или есть хитрости вроде
int i = i;
, которые не позволяют gcc выдавать «неинициализированные предупреждения»?