C 为什么编译器报告';可以在未初始化的情况下在此函数中使用';?
我正在编写一个linux模块,下面是代码片段 抱怨统一使用变量,但我想我已经检查过了 使用前有足够的检查,我想可能有关系 ERR_PTR和PTR_ERR宏,但我不知道为什么。 有人能帮我解释一下吗?先谢谢你C 为什么编译器报告';可以在未初始化的情况下在此函数中使用';?,c,initialization,compiler-warnings,C,Initialization,Compiler Warnings,我正在编写一个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 *
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)
^
更新:01-30-2015: 我认为根本原因是
long
到int
的转换。PTR\u ERR()
函数会将指针转换为long
,但在
在上面的代码中,test\u value\u get()
将long
转换为int
,并返回它
由于我使用的是一台64位的机器,所以长码可能会
被截断为较低的32位,例如,如果它是0xFFFFFE00000000,
返回值将被削减为0,然后如果(err)
不满足,
这导致测试值被错误使用。
(虽然errno不会大于4095,但编译器似乎没有意识到,最近的溢出值将是0xFFFFFE00000000)
有什么意见吗?检查下面的执行链
在my\u test()
中,调用test\u value\u get()
test_alloc_value()代码>失败,如果(IS_ERR(p))
为真
*值=*p代码>未执行
在my_test()
中,if(test_value)
展示了先读后写的场景
这意味着,尽管可能性更小,但仍然有一种方法,test\u值
可以在未初始化的情况下使用。那么,你的编译器不对吗
为了避免这种情况,在错误情况下[如果(IS_ERR(p))
为TRUE.]另外,将*值
初始化为一些默认值,如0
if (IS_ERR(p))
{
if (value) //NULL pointer safe
*value = 0; // set *value in error case also
return PTR_ERR(p);
}
检查下面的执行链
在my\u test()
中,调用test\u value\u get()
test_alloc_value()代码>失败,如果(IS_ERR(p))
为真
*值=*p代码>未执行
在my_test()
中,if(test_value)
展示了先读后写的场景
这意味着,尽管可能性更小,但仍然有一种方法,test\u值
可以在未初始化的情况下使用。那么,你的编译器不对吗
为了避免这种情况,在错误情况下[如果(IS_ERR(p))
为TRUE.]另外,将*值
初始化为一些默认值,如0
if (IS_ERR(p))
{
if (value) //NULL pointer safe
*value = 0; // set *value in error case also
return PTR_ERR(p);
}
test\u value声明在哪里?int test\u value
是全局的?显然不是您的完整代码,但是在test\u value\u get
中,并不是所有可能的路径都在函数中更改(初始化)test\u value
(也称为value
)。只有看到此代码,它才能被统一化!如果test\u value
有静态存储持续时间,那么按照标准,它是零初始化的,我看不出它除了兜售静态存储持续时间之外还能做什么。C11§6.7.9初始化,第10页,“如果它有算术类型,则初始化为(正或无符号)零”;否则,请发布MCVE。测试值在哪里声明?int test\u值
是全局的?显然不是完整的代码,但在test\u值
中,并非所有可能的路径都会更改(初始化)函数中的test\u value
(也称为value
),只有看到此代码,才能将其统一化!如果test\u value
有静态存储持续时间,那么按照标准,它是零初始化的,我看不出它除了兜售静态存储持续时间之外还能做什么。C11§6.7.9初始化,第10页,“如果它有算术类型,则初始化为(正或无符号)零”;否则,请发布MCVE。如果为错误(p)
为真,则OPs代码的修复程序可以将*值设置为零。@meskobalazs非常正确,先生。我只是更新了一下。:-)test\u值
不可能未初始化。在执行链中,if(err)
必然为true,导致返回
,因此控制流永远不会达到if(test\u值)
。唯一的问题是编译器没有意识到这一点。也就是说,警告是假阳性。@sepp2k您说得很对,先生,但为了100%确定,我们需要查看PTR\u ERR
定义。如果没有这一点,那么从技术上讲,就有可能(不过我希望我是错的)。:-)您好,我已经更新了内容,请您帮忙看看,谢谢。如果为错误(p)
为真,则OPs代码的修复程序可能会将*值设置为零。@meskobalazs非常正确,先生。我只是更新了一下。:-)test\u值
不可能未初始化。在执行链中,if(err)
必然为true,导致返回
,因此控制流永远不会达到if(test\u值)
。唯一的问题是编译器没有意识到这一点。也就是说,警告是假阳性。@sepp2k您说得很对,先生,但为了100%确定,我们需要查看PTR\u ERR
定义。如果没有这一点,那么从技术上讲,就有可能(不过我希望我是错的)。:-)您好,我已经更新了内容,请您帮忙看看,谢谢