Die*_*Epp 17 c gcc warnings longjmp
我有这样的功能:
#include <setjmp.h>
jmp_buf buf;
void func2(int g);
extern int some_global;
void func(int x)
{
if (setjmp(buf))
return;
if (some_global)
x += 5;
func2(x);
}
Run Code Online (Sandbox Code Playgroud)
GCC(gcc(Debian 4.4.5-8)4.4.5)发出警告:
test.c: In function ‘func’: test.c:5: warning: argument ‘x’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Wclobbered]
为什么????我的意思是,显然我不在乎是否x被破坏,因为它不可能在setjmp返回后使用.即使编译器应该知道一些非常明显的东西,因为它具有某种特殊的知识setjmp.
我的主要兴趣是找到我继承的代码库中的错误,因此,"使用这种编码风格"并不是我正在寻找的建议.然而,这里有许多奇怪的曲折.例如,如果x是局部变量而不是参数,那么GCC不会抱怨.此外,GCC不会在没有if (some_global)线的情况下抱怨.尼斯.有些事情搞砸了GCC的流量分析,或者GCC知道我不知道的事情.
所以,
是否有一种简单的方法来抑制此函数的此警告,就像您可以将未使用的参数转换为(void)?
或者我只是在项目范围内禁止警告?
或者我错过了什么?
更新:让我与您分享一个不会产生警告的略有不同的版本:
#include <setjmp.h>
jmp_buf buf;
void func2(int g);
extern int some_global;
void func(int y)
{
int x = y;
if (setjmp(buf))
return;
if (some_global)
x += 5;
func2(x);
}
Run Code Online (Sandbox Code Playgroud)
Die*_*Epp 12
在刮网之后,重新阅读GCC文档,我遇到了这个:
功能属性:
returns_twice该
returns_twice属性告诉编译器函数可能返回多次.在调用这样的函数之前,编译器将确保所有寄存器都已死,并且会在第二次从函数返回后发出可能被破坏的变量的警告.这些功能的例子是setjmp和vfork.longjmp此类函数的类似对应项(如果有)可能需要使用该noreturn属性进行标记.
因此,GCC似乎没有任何"特殊知识" setjmp,它只是暗示它确实如此.所有它知道的是setjmp返回两次,而不是它总是在第一次返回0并且之后返回非零.天哪,那本来不错.
来自man longjmp:
如果满足以下所有条件,则在调用longjmp()之后未指定自动变量的值:
· they are local to the function that made the corresponding setjmp(3)
call;
· their values are changed between the calls to setjmp(3) and
longjmp(); and
· they are not declared as volatile.
Run Code Online (Sandbox Code Playgroud)
碰巧,x第一个示例中的变量符合条件:
setjmp如果some_global为真,它的值可能会改变.所以它的价值可能是未指定的(破坏).
关于为什么第二个版本没有发出警告......不知道.
| 归档时间: |
|
| 查看次数: |
6137 次 |
| 最近记录: |