【问题标题】:How can clang warn me if I fail to initialize a variable while using ARC?如果我在使用 ARC 时未能初始化变量,clang 如何警告我?
【发布时间】:2012-10-06 22:47:40
【问题描述】:

我忘记初始化一个局部变量,使用它时没有收到任何警告。由于我使用的是ARC,因此变量被初始化为nil,所以没有造成任何伤害,但是当我使用未初始化的值时,我仍然需要一个警告。如果我禁用 ARC,我会收到预期的警告。

NSString *foo;
NSString *baz;
if (bar) {
    foo = @"fizz";
} else {
    foo = @"buzz";
}
NSLog(@"foo: %@", foo);  // foo: (fizz|buzz)
NSLog(@"baz: %@", baz);  // baz: (null)

没有 ARC:

/blah/blah/blah/Blah.m:14:18: note: initialize the variable 'foo' to silence this warning
NSString *foo;
             ^

--编辑--

I've figured out how to make uninitialized values impossible using local blocks。这样就不需要警告了。

【问题讨论】:

    标签: objective-c automatic-ref-counting clang clang-static-analyzer


    【解决方案1】:

    Martin R is correct:

    使用 ARC,指向 Objective C 对象的指针会自动 初始化为零,所以没有“未初始化的值” 编译器可以发出警告。

    但是,我通过使用本地块来初始化变量完全避免了这个问题。该块保证所有路径都以return 结尾,这意味着我的变量保证被初始化。

    这个例子应该是这样写的:

    NSString *foo = ^{
        if (bar) {
            return @"fizz";
        } else {
            return @"buzz";
        }
    }();
    NSLog(@"foo: %@", foo);  // foo: (fizz|buzz)
    

    该块是堆栈分配的,因此不会产生超出正常函数调用的任何开销。

    【讨论】:

      【解决方案2】:

      Clang 有一个选项 -Wuninitialized 看起来应该做你想做的事,但正如另一个答案中指出的那样,变量保证在 ARC 下被初始化为 0/nil

      【讨论】:

      • 不幸的是,这个选项似乎不适用于对象引用(适用于值类型),至少在 Clang 4.4 中。该选项由 Xcode 项目设置中的“未初始化变量”开关设置。
      【解决方案3】:

      使用 ARC,指向 Objective C 对象的指针会自动初始化为 nil,因此不会出现编译器可以警告的“未初始化值”。

      【讨论】:

      • 虽然没有编译器可以警告的“未初始化值”,但也没有一个用于整数的值。未初始化的警告是通过简单分析源码完成的,第一次使用前有赋值吗?此测试的逻辑存在于 Clang 中,并且仍然用于值类型。只是 Clang 设计者选择在这种情况下不发出警告。如果您希望收到警告,请向 Apple 提交增强请求。
      • @CRD:我刚刚重新阅读了您的评论,我不确定我是否理解正确。 Clang/ARC 文档说明了“可保留对象指针类型的对象”:“初始化发生在对象的生命周期开始时……首先,使用原始语义将空指针存储到左值中”。 - 所以在第一次使用之前(由 ARC 编译器生成)对变量进行了显式赋值,而对于其他变量(例如整数)则不这样做。这就是您没有收到警告的原因。
      • 可以将初始化描述为编译器添加的隐式赋值,而不是源中的显式。因此,如果在第一次使用之前没有进行显式分配,也实现了分配分析的编译器不会面临警告中的技术原因。这样的分析询问“这个变量被分配了吗?”这是类型(和值 - 没有“未初始化的值”)独立的。但是,发出警告是否好是值得商榷的;有些将基于此进行编码,而另一些(例如 OP)则不会。编译器开关/编译指示可能是合理的。
      猜你喜欢
      • 2017-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多