Thursday, January 2, 2003

Pointers in Cocoa

I don’t quite understand what Victor Ng is on about. Objective-C ivar pointers are initialized to nil, and you should get a compiler warning if you attempt to use an uninitialized local variable. But he’s right, of course, that it’s easy to send a message to a released object. Unlike Victor, I don’t set pointers to released objects to nil because I think that would make it harder to detect errors; Objective-C will happily send any message to nil without complaining. I’d rather use NSZombieEnabled during testing.

5 Comments RSS · Twitter

Are you sure?

What's NSZombieEnabled? I haven't seen a reference to that in the few tutorials that I've read.

I just wrote a small unit test using OCUnit and my tests behave as though pointers are not initialized properly - both of these tests failed.

Here's my test code:

-(void)testNSDateInitTest

   /*

    prove to myself that pointers are initlialized to nil

    */

{

   NSDate* date;

   [self assertTrue:(date == nil) message:@"date should be nil if pointers are initialized"];

}

-(void)testIdInitTest

   /*

    prove to myself that pointers are initlialized to nil

    */

{

   id obj;

   [self assertTrue:(obj == nil) message:@"obj should be nil if pointers are initialized"];

}

Your example is for local (automatic) variables, which can hold garbage if you don’t initialize them. I haven’t found this to be much of a problem because of compiler warnings and because I usually initialize them in the same line that I declare them.

Ivars are initialized: According to Apple, “the alloc method dynamically allocates memory for the new object’s instance variables and initializes them all to 0.”

From NSDebug.h: FOUNDATION_EXPORT BOOL NSZombieEnabled; Enable object zombies. When an object is deallocated, its isa pointer is modified to be that of a “zombie” class (whether or not the storage is then freed can be controlled by the NSDeallocateZombies variable). Messages sent to the zombie object cause logged messages and can be broken on in a debugger. The default is NO.

Ok - so this explains what was going on. I got those SIGBUS errors because of uninitialized pointers in my test code.

Now about those compiler errors- I never get any.

I cleaned up my project and recompiled and I didn't get any warnings at all. Do you have extra flags turned on?

The relevant flag is -Wuninitialized. I believe it's on by default, but GCC 3 ignores it if the optimizer is off (i.e. you are doing a Development build).

It's not so much that gcc ignores it, as that the optimizer is the part of the compiler that does the data flow analysis. If the optimizer is off, gcc doesn't have a chance to notice that the variable could be uninitialized.

Leave a Comment