Objective-C本机异常语法的虚假“变量可能被删除”警告

Objective-C本机异常语法的虚假“变量可能被删除”警告,objective-c,gcc,Objective C,Gcc,当使用-Wextra警告标志编译带有@try blocks的Objective-C代码时,有时会收到“变量'foo'可能被'longjmp'或'vfork'阻塞”的警告。尽管文本具有特定的性质,但这适用于具有该属性的所有函数,包括异常处理运行时函数。警告与C规范中的此文本有关: 在调用longjmp函数时,所有可访问对象都有值,抽象机器的所有其他组件都有状态,除了包含相应setjmp宏调用的函数本地的自动存储持续时间对象的值是不确定的,这些对象没有volatile限定类型,并且在setjmp调用

当使用-Wextra警告标志编译带有@try blocks的Objective-C代码时,有时会收到“变量'foo'可能被'longjmp'或'vfork'阻塞”的警告。尽管文本具有特定的性质,但这适用于具有该属性的所有函数,包括异常处理运行时函数。警告与C规范中的此文本有关:

在调用longjmp函数时,所有可访问对象都有值,抽象机器的所有其他组件都有状态,除了包含相应setjmp宏调用的函数本地的自动存储持续时间对象的值是不确定的,这些对象没有volatile限定类型,并且在setjmp调用和longjmp调用之间发生了更改

一般来说,我可以通过将受影响的变量标记为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 (...) {}
}
当使用apple gcc 4.0或4.2而不是llvm gcc并启用-Wextra和优化为i386构建时,会出现警告。请注意,这不是一个真正的问题,因为如果捕获到异常,将不会使用该值

手册页表明此警告由-Wuninitialized控制,但事实并非如此。使用-Wuninitialized不会触发它,但使用-Wextra-Wno uninitialized会触发它


所以问题是,除了禁用-Wextra或切换编译器之外,还有其他方法可以抑制此警告吗?作为一个警告受虐狂,我当然在使用-Werror。

引用gcc手册:注意,一些警告标志不是由-Wall暗示的。他们中的一些人警告用户通常不认为有问题的结构,但偶尔你可能想检查一下。其他人则警告某些情况下必须或难以避免的构造,并且没有简单的方法修改代码以抑制警告。其中一些由-Wextra启用,但其中许多必须单独启用

基本上,-WUTH-WError告诉编译器,即使我做很多人都不认为有问题的事情,也要中断我的构建。我不明白为什么这是可取的,虽然我应该注意到,我有一个根深蒂固的个人仇视-沃罗的其他原因,所以我可能是有偏见的


为了比不这样做更有用,也许-Wno clobber?

的确,-Wextra启用的一些警告可能会令人讨厌,因此,通常可以有选择地关闭它们是一件好事。显然,除了这一个:正如Jeff“lapcat”Johnson在Twitter上指出的那样,这个真正的编译器Bug™ 前一段时间已为@synchronized修复,但未为@try修复。