2

我忘了初始化一个局部变量,当我使用它时我没有任何警告。由于我使用的是ARC,变量初始化为nil,所以没有造成任何伤害,但我仍然希望在使用未初始化的值时发出警告。如果我禁用ARC,我会收到我期望的警告。如果在使用ARC时未能初始化变量,clang会如何警告我?

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。这消除了警告的需要。

回答

4

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

+0

虽然没有“未初始化的值”,但编译器可以提出警告,也没有一个用于整数。未初始化的警告是通过对源代码的简单分析完成的,在第一次使用之前是否有分配?此测试的逻辑存在于Clang中,并仍用于值类型。简单的叮当设计师*在这种情况下选择*不要给出警告。如果您希望警告将提交请求提交给Apple。 – CRD

+0

@CRD:我只是重新阅读你的评论,我不确定我是否正确理解它。 [Clang/ARC](http://clang.llvm.org/docs/AutomaticReferenceCounting.html#semantics)文档陈述了“可保留对象指针类型的对象”:*“初始化发生在对象的生命周期开始时......首先,使用原语语义“*”将空指针存储到左值。 - 所以在第一次使用(由ARC编译器生成)之前,有一个*显式赋值给变量,而不是其他变量(如整数)。这就是为什么你没有得到警告。 –

+0

可以将初始化描述为由编译器添加的* implicit *赋值,它不是源*中的* explicit *。因此,如果在第一次使用之前没有做出明确的分配,那么也执行分配分析的编译器在警告中不会面临*技术*原因。这样的分析要求“有这个*变量*被分配到了吗?”这是类型(和值 - 无“非空值”)独立。但是,是否有利于发出警告是值得商榷的;有些将基于此编码,其他(例如,g OP)不会。编译器开关/编译指示可能是合理的。 – CRD

2

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

+1

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

0

Martin R is correct

随着ARC,指针到目标C的对象是自动初始化 为nil,所以没有“未初始化值”其中 编译器可以发出警告。

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

的例子是写的正是如此:

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

该块栈上分配的,所以它不会产生超出正常的函数调用的任何开销。

相关问题