我有这样的function:
#include 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); }
GCC(gcc(Debian 4.4.5-8)4.4.5)发出警告:
test.c:在函数'func'中: test.c:5:警告:参数'x'可能被'longjmp'或'vfork'破坏[-Wclobbered]
为什么???? 我的意思是,显然我不在乎x
是否被破坏,因为它在setjmp
返回后不可能被使用。 即使编译器应该知道一些非常明显的东西,因为它具有某种特殊的setjmp
知识。
我的主要兴趣是找到我inheritance的代码库中的错误,因此,“使用这种编码风格代替”并不是我正在寻找的建议。 然而,这里有许多奇怪的曲折。 例如,如果x
是局部变量而不是参数,那么GCC不会抱怨。 此外, if (some_global)
没有if (some_global)
行,GCC不会抱怨。 尼斯。 有些事情搞砸了GCC的流量分析,或者GCC知道我不知道的事情。
所以,
更新:让我与您分享一个不会产生警告的略有不同的版本:
#include 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); }
在刮网之后,重新阅读GCC文档,我遇到了这个:
function属性:
returns_twice
returns_twice
属性告诉编译器函数可能返回多次。 在调用这样的函数之前,编译器将确保所有寄存器都已死,并且会在第二次从函数返回后发出可能被破坏的变量的警告。 这些函数的例子是setjmp
和vfork
。 这种函数的longjmp
like对应物(如果有的话)可能需要用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.
碰巧,第一个示例中的x
变量符合条件:
所以它的价值可能是未指定的(破坏)。
关于为什么第二个版本没有发出警告……不知道。
需要了解更多c/c++开发分享这些破坏性变量警告有何意义?,也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)!
以上就是c/c++开发分享这些破坏性变量警告有何意义?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/980223.html