【发布时间】:2015-01-29 11:45:18
【问题描述】:
我正在写一个 linux 模块,这里是代码片段。它 抱怨统一使用变量,但我想我已经检查过了 使用前有足够的检查。我认为这可能与 ERR_PTR 和 PTR_ERR 宏,但我不知道为什么。 有人可以帮忙解释一下吗?提前谢谢你。
static inline void * __must_check ERR_PTR(long error)
{
return (void *) error;
}
static inline long __must_check PTR_ERR(__force const void *ptr)
{
return (long) ptr;
}
#define MAX_ERRNO 4095
#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO)
static inline bool __must_check IS_ERR(__force const void *ptr)
{
return IS_ERR_VALUE((unsigned long)ptr);
}
void* test_alloc_value(void)
{
char* p = kmalloc(100,GFP_KERNEL);
if(!p)
return ERR_PTR(-ENOMEM);
memset(p,100,0);
return p;
}
int test_value_get(int *value)
{
int err = 0;
char *p;
p = test_alloc_value();
if (IS_ERR(p))
return PTR_ERR(p);
*value = *p;
return err;
}
void my_test(void)
{
int test_value;
int err = test_value_get(&test_value);
if(err)
return err;
if(test_value) //warnings,see below
return 0;
}
错误信息是:
warning: ‘test_value’ may be used uninitialized in this function [-Wmaybe-uninitialized]
if(test_value)
^
更新:2015 年 1 月 30 日:
我认为根本原因是 long 到 int 的转换。 PTR_ERR() 函数会将指针转换为long,但在
以上代码,test_value_get() 会将long 转换为int,并返回
到my_test()。由于我使用的是64位机器,所以很长可能
被截断到低32位,例如,如果是0xffffffffe00000000,
返回值将被削减为 0,然后if(err) 将不满足,
这导致test_value 以错误的方式使用。
(虽然 errno 不会大于 4095,但编译器似乎没有意识到,最近的溢出值为 0xffffffffe00000000)
有cmets吗?
【问题讨论】:
-
test_value 在哪里声明?
-
int test_value是全球性的吗? -
显然不是您的完整代码,但在
test_value_get中,并非所有可能的路径都会在函数中更改(初始化)test_value(又名value)。 -
只看到这段代码,可能单元化了!
-
如果
test_value具有静态存储持续时间,则根据标准将其初始化为零,而且鉴于您发布的代码很少,我看不出它可以是什么,除了吹捧静态存储持续时间. C11 §6.7.9 初始化,p10,“如果它具有算术类型,则将其初始化为(正或无符号)零;”如果不是这样,请发布 MCVE。
标签: c initialization compiler-warnings