当使用@try
警告标志用-Wextra
块编译Objective-C代码时,我有时会收到“变量'foo'形式的警告,可能会被'longjmp'或''破坏的vfork'”。 (尽管文本的特定性质,这适用于具有returns_twice
属性的所有函数,包括异常处理运行时函数。)警告与C规范中的此文本有关:
所有可访问的对象都有值,并且抽象机器的所有其他组件在调用longjmp函数时都具有状态,除了包含调用的函数的本地自动存储持续时间的对象的值没有volatile限定类型并且在setjmp调用和longjmp调用之间已经更改的相应setjmp宏是不确定的。
通常我可以通过将受影响的变量标记为volatile或将代码放入外联函数来解决此问题。但是,我现在看到它用于库中的内联函数。这是一个浓缩的测试用例:
static inline uint64_t Foo(void)
{
union
{
int32_t a;
uint64_t b;
} l;
l.a = 1; // warning: variable 'l' might be clobbered by 'longjmp' or 'vfork'
return l.b;
}
void Test(uint64_t *value)
{
@try
{
*value = Foo();
}
@catch (...) {}
}
使用带有-Wextra
的apple-gcc 4.0或4.2(不是llvm-gcc)构建i386并启用优化时会出现警告。请注意,这不是一个真正的问题,因为如果捕获到异常,则不会使用该值。
手册页建议此警告由-Wuninitialized
控制,但事实并非如此。使用-Wuninitialized
不会触发它,但使用-Wextra -Wno-uninitialized
会触发它。
所以问题是,除了禁用-Wextra
或切换编译器之外,还有什么方法可以抑制此警告吗? (作为一个警告masochist,我当然使用-Werror
。)
答案 0 :(得分:0)
请参阅gcc手册:“请注意,-Wall并未暗示某些警告标志。有些人警告用户通常不会考虑可疑的结构,但有时您可能希望检查这些结构;其他警告有关结构的建议在某些情况下是必要的或难以避免的,并且没有简单的方法来修改代码以抑制警告。其中一些是由-Wextra启用的,但其中许多必须单独启用。“
基本上,-Wextra -Werror告诉编译器“即使我做了许多人根本不认为有问题的事情,也要打破我的构建”。我不明白为什么这是可取的(虽然我应该注意到我有一个根深蒂固的个人仇杀反对 - 出于其他原因的错误,所以我可能有偏见。)
试图比“不要那样做”更有用,也许是-Wno-clobber?