对于Objective-C本机异常语法,Bogus“变量可能被破坏”警告

时间:2010-12-28 21:59:17

标签: objective-c gcc

当使用@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。)

1 个答案:

答案 0 :(得分:0)

请参阅gcc手册:“请注意,-Wall并未暗示某些警告标志。有些人警告用户通常不会考虑可疑的结构,但有时您可能希望检查这些结构;其他警告有关结构的建议在某些情况下是必要的或难以避免的,并且没有简单的方法来修改代码以抑制警告。其中一些是由-Wextra启用的,但其中许多必须单独启用。“

基本上,-Wextra -Werror告诉编译器“即使我做了许多人根本不认为有问题的事情,也要打破我的构建”。我不明白为什么这是可取的(虽然我应该注意到我有一个根深蒂固的个人仇杀反对 - 出于其他原因的错误,所以我可能有偏见。)

试图比“不要那样做”更有用,也许是-Wno-clobber?