tags:

views:

59

answers:

4

While looking through some code, I found two different code snippets for initialization. I don't mean the method names, but the round brackets.

This one has just two of them:

if (self = [super initWithFrame:frame]) {

That's the way I do it all the time, and it seems to work. Now in an Apple example I found this:

if ((self = [super init])) {

Do I have to put it twice into round brackets here? Or is it just fine to put it in one pair of brackets, like the first example?

+3  A: 

One pair of brackets is just fine

I call them "paranoia brackets" :)

EDIT: some C/C++ compilers will issue a warning because of the use of the assignment operator (it will say something like "did you mean ==" ?). Using extra parentheses prevents this warning. But XCode doesn't show this kind of warning, so there's no need to do that.

Philippe Leybaert
ha ha... I too have that paranoia...
Mugunth Kumar
+2  A: 

Looks like a cut and paste error to me! (Or a lover of Lisp.) There is no good reason to have the second pair of brackets but, as you note, it's not actually harmful.

Stephen Darlington
+1  A: 

If I've got this right the first one checks that the assignment self = [super initWithFrame:frame] happens and the second one checks that the result of that assignment is true

But this could just be a lack of tea speaking...

James Raybould
That's also what I had in mind. On the other hand, what would determine if it is true or false? It could check for thruthyness of falsyness, which in this case would match the "happened" and "not happened", so in the end it makes no sense to me...
HelloMoon
It would return true unless it is nil. Just like you can do if(!anObject) { ... } which will only get executed if it is equal to nil. Usually I use !something rather than something == nil because !something is very clear and you can think of it as If there is no something, do this.
Mk12
+2  A: 

In some languages, if( foo = bar ) implies that the assignment was correctly applied. So the calls:

if( ( foo = bar ) )

would evaluate the assignment and return the result as the outer () act as a LHS, ie,

blah = foo = bar

the outer () act sort of like blah.

In ANSI C and it's children C++ and Objective-C this isn't strictly necessary. However as has been mentioned some compilers will issue a warning since the "=" / "==" type-o can be a nasty one. That type-o led to the idiom of putting the invariant or constant at the left hand side to cause compile time catching of the problem:

if( nil == foo )

if both sides are variables though it's still possibly a mistake.

There is a good reason for doing this even though gcc isn't warning you or evaluating things differently.

If you are writing code in a team environment your peers may not be sure you meant "=" or just mistyped "==", causing them to peer more closely at what you're doing even though there's no need to. In the style of "write once to be read 1000 times" you put in clues to prevent people from having to waste time when reading your code. For instance, use clear and spelled out variable names (no economy on bytes these days!). Don't use obtuse and overly optimized constructs in areas that aren't drags on performance - write your code cleanly.

In this case, use (( )) to indicate you knew it was "=" not "==".

Don't forget, Apple is writing their examples for not just a dozen people to read, but potentially every man, woman, and child on earth to read now and in the future. Clarity is of upmost importance.

groundhog