Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

! vs == nil in objective-c [duplicate]

If you have an object like NSString *someString, what is the difference, if any, between

if (!someString)

vs

if (someString == nil)

Thanks!

like image 250
Crystal Avatar asked Jul 21 '11 20:07

Crystal


People also ask

How do I check if an object is nil in Objective-C?

Any message to nil will return a result which is the equivalent to 0 for the type requested. Since the 0 for a boolean is NO, that is the result. Show activity on this post. Hope it helps.

Is NULL always 0?

The null pointer constant is always 0. The NULL macro may be defined by the implementation as a naked 0 , or a cast expression like (void *) 0 , or some other zero-valued integer expression (hence the "implementation defined" language in the standard). The null pointer value may be something other than 0.


2 Answers

The first syntax you use:

 if (!someString)

exploits a sort of "ambiguity" of C deriving from the fact that the original standard of C lacked a proper boolean type. Therefore, any integer value equalling 0 was interpreted as "false", and any integer value different from "0" was taken as "true". The meaning of ! is therefore defined based on this convention and current versions of the C standard have kept the original definition for compatibility.

In your specific case, someString is a pointer, so it is first converted to an integer, then ! someString is interpreted as a bool value of true when someString points at the location 0x000000, otherwise it evals to "true".

This is fine in most conditions (I would say always), but in theory, NULL/nil could be different from 0x000000 under certain compilers, so (in very theory) it would be better to use the second syntax, which is more explicit:

 if (someString == nil)

It is anyway more readable and since someString is not an integer (rather a pointer), IMO, better practice in general.

EDIT: about the definition of NULL...

Whether the C standard defines NULL to be 0 is an interesting topic for me...

According to C99 standard, section 7.17, "Common definitions ":

NULL [which] expands to an implementation-defined null pointer constant;

So, NULL is defined in stddef.h to an implementation-defined null pointer constant... The same document on page 47 states:

An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.55) If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.

So, the null pointer constant (which is (void*)0) can be converted to a null pointer and this is guaranteed to compare unequal to a pointer to any object or function.

So, I think that basically it depends on whether the implementation decides that the result of converting a null pointer constant to a null pointer produces a pointer which converted back to an integer gives 0. It is not clear that a null pointer interpreted as an integer equals 0.

I would say that the standard really try and enforce the null pointer being 0, but leaves the door open to systems where the null pointer was not 0.

like image 126
sergio Avatar answered Oct 13 '22 23:10

sergio


For most pointers, they're equivalent, though most coders I know prefer the former as it's more concise.

For weakly linked symbols, the former resolves the symbol (and will cause a crash if it's missing) while an explicit comparison against nil or NULL will not.

like image 38
Jonathan Grynspan Avatar answered Oct 13 '22 21:10

Jonathan Grynspan