2

I forgot to initialize a local variable, and I got no warning when I used it. Since I'm using ARC, the variable was initialized to nil, so no harm was done, but I still want a warning when I used an uninitialized value. If I disable ARC, I get the warning I expect.

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

Without ARC:

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

--EDIT--

I've figured out how to make uninitialized values impossible using local blocks. This obviates the need for the warning.

Heath Borders
  • 30,998
  • 16
  • 147
  • 256

3 Answers3

5

With ARC, pointers to Objective C objects are automatically initialized to nil, so there is no "uninitialized value" which the compiler can warn about.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • While there is no "uninitialized value" the compiler can warn about, there is not one for, say, integers either. The uninitialized warning is done by a simple analysis of the source, is there an assignment before the first use? The logic for this test exists in Clang, and is still used for value types. Simply the Clang designers *chose* not to give a warning in this case. If you'd like the warning submit an enhancement request to Apple. – CRD Oct 16 '12 at 20:55
  • @CRD: I just re-read your comment, and I am not sure that I understand it correctly. The [Clang/ARC](http://clang.llvm.org/docs/AutomaticReferenceCounting.html#semantics) documentation states about "objects of retainable object pointer type": *"Initialization occurs when an object’s lifetime begins ... First, a null pointer is stored into the lvalue using primitive semantics"*. - So there is an *explicit assignment* to the variable before first use (generated by the ARC compiler), which is not done for other variables such as integers. That's why you don't get a warning. – Martin R Apr 17 '13 at 12:56
  • One could describe the initialisation as an *implicit* assignment added by the compiler, it's not *explicit* in the source. As such the compiler, which also implements the assignment analysis, faces no *technical* reason in warning if no explicit assignment has been made prior to first use. Such analyses ask "has this *variable* been assigned to yet?" which is type (and value - no "unintialized value") independent. However, whether it is good to issue a warning or not is debatable; some will code based on this, others (e.g the OP) won't. A compiler switch/pragma could be justified. – CRD Apr 17 '13 at 18:16
2

Clang has an option -Wuninitialized that looks like it should do what you want, but as pointed out in another answer, variables are guaranteed to be initialized to 0/nil under ARC.

Isaac
  • 10,668
  • 5
  • 59
  • 68
  • 1
    Unfortunately this option does not seem to work for object references (works fine for value types), at least in Clang 4.4. The option is set by the "Uninitialized Variables" switch in Xcode's project settings. – CRD Oct 16 '12 at 19:27
0

Martin R is correct:

With ARC, pointers to Objective C objects are automatically initialized to nil, so there is no "uninitialized value" which the compiler can warn about.

However, I've avoided this problem altogether by using local blocks to initialize variables. The block guarantees that all paths end in a return, which means that my variable is guaranteed to be initialized.

The example would be written thusly:

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

The block is stack-allocated, so it doesn't incur any overhead beyond a normal function call.

Community
  • 1
  • 1
Heath Borders
  • 30,998
  • 16
  • 147
  • 256