Live data from Hacker News

nil, Nil, NULL, NSNull

nshipster.com

31–40 of 66 posts

Re: nil, Nil, NULL, NSNull

#31
post #11

Nice article, but I just wanted to throw out that if being able to call a class method on a null object in C++ is desirable, you can actually check for that condition instead of just crashing. if(!this) return false; // Or whatever Of course it's open for debate as to whether this is something to encourage, but it can help from having to use a Null Object pattern in some situations.

This isn't a good idea since even it happens to work it invokes undefined behaviour. If you change the method to virtual it will crash.

I think you mean non-virtual method, not 'class method' or static method which wouldn't have a this pointer.

Re: nil, Nil, NULL, NSNull

#32
Java is not identical to Obj-C but the 'null' fiasco is mindboggling...

Back when the book *"Effective Java" came out, a truly great advice was to use empty arrays everywhere you could instead of null.

The second enlightenment came to me when the smart brains at JetBrains decided to ship IntelliJ IDEA with the @NotNull annotation. I basically started to annotate as many methods returning something as @NotNull and then saw the number of NullPointerException go drastically down.

It's not possible everywhere but once you start to think about it, you realize that you don't need nearly as many null references as you think you did.

Then you started having IntelliJ IDEA warning you real-time (even on incomplete source file) about "reference xxx is never going to be null" (so the non-null check is pointless) or "warning: reference to xxx may be null". Great stuff. Years later there are still 99% of all the Java codebase not using the @NotNull annotation. Sad but true.

Now of course other language's take on the subject are interesting too: the maybe monad, the way Clojure deals with empty / nil sequences, etc.

Re: nil, Nil, NULL, NSNull

#33
post #15

Earlier quoted context omitted.

`[a compare:b]` returns 0 both if they are equal and if a is nil.

Cheers for the counter-example. I can't think of a compare method in the Objective-C core lib (the biggest nil-swallowing lib I know of). Does anyone know of one? Would be interesting to see how it's handled and if it causes issues. You could return an enum, which would allow you to use non-obvious values (Lower = 1, Equal = 2, Higher = 3), though this would make it a bit of a pain to interface with C-style libs. Obv…

> I can't think of a compare method in the Objective-C core lib (the biggest nil-swallowing lib I know of). Does anyone know of one? Would be interesting to see how it's handled and if it causes issues.

Maybe I misunderstood you, but there is plenty of compare:'s in Cocoa: http://cl.ly/image/1a112f1B1W1g.

They all return an enum that's either -1, 0 or 1.

Re: nil, Nil, NULL, NSNull

#34
Just a reminder for C and C++ programmers: NULL considered harmful. Instead, use a literal 0 or (void * ) 0 in portable code.

In the C Standard, an implementation can define NULL as either 0 or (void * ) 0. For an example of how that can go terribly wrong, consider the following:

    printf ("%p\n", NULL)
on an architecture where sizeof (int) != sizeof (ptr)

Re: nil, Nil, NULL, NSNull

#35
post #31
post #11

Nice article, but I just wanted to throw out that if being able to call a class method on a null object in C++ is desirable, you can actually check for that condition instead of just crashing. if(!this) return false; // Or whatever Of course it's open for debate as to whether this is something to encourage, but it can help from having to use a Null Object pattern in some situations.

This isn't a good idea since even it happens to work it invokes undefined behaviour. If you change the method to virtual it will crash. I think you mean non-virtual method, not 'class method' or static method which wouldn't have a this pointer.

That's a good point, calling a virtual method on a null pointer is the source of some backtraces that seem to start a few bytes past 0.

Naming things is always difficult, but I meant class method, although what I should have said was non-virtual class method, which is possible in C++. Both virtual and non-virtual have "this" pointers, the difference is whether the class method to call is looked up at runtime or compile-time, so I still would consider both "methods". I didn't learn OOP from Smalltalk so I may be abusing the terminology (it's not intentional).

Re: nil, Nil, NULL, NSNull

#36
post #34

Just a reminder for C and C++ programmers: NULL considered harmful. Instead, use a literal 0 or (void * ) 0 in portable code. In the C Standard, an implementation can define NULL as either 0 or (void * ) 0. For an example of how that can go terribly wrong, consider the following: printf ("%p\n", NULL) on an architecture where sizeof (int) != sizeof (ptr)

c++11 also has nullptr

Re: nil, Nil, NULL, NSNull

#37
post #34

Just a reminder for C and C++ programmers: NULL considered harmful. Instead, use a literal 0 or (void * ) 0 in portable code. In the C Standard, an implementation can define NULL as either 0 or (void * ) 0. For an example of how that can go terribly wrong, consider the following: printf ("%p\n", NULL) on an architecture where sizeof (int) != sizeof (ptr)

It's actually a different answer for C or C++ programmers.

NULL should be defined as ((void * )0) for C always (and you should define your own NULL to enforce that if necessary in varargs functions). This is safe because C allows conversion from void * to other pointer types.

C++ does not allow conversion from void * to other pointer types, so what you were supposed to do was use plain 0, which introduced exactly the issue you mention (and which has bitten me before trying to use a C library from C++, where NULL was defined as plain 0).

With C++11 you should use nullptr, which does the right thing. Some implementations define NULL in C++ to a vendor-provided symbol which emulates nullptr so it might be safe to use NULL. If you have C++98 only and don't want to risk NULL then you should use static_cast(0) (where T is the actual pointer type), which is admittedly clunky.

Re: nil, Nil, NULL, NSNull

#38

Any use cases for Nil, that is, the class pointer to nothing? I've not seen it in the wild (which isn't saying a great deal.)

You could use it to test whether or not you really got a class from NSClassFromString(). For instance:

  Class _myClass;
  // aClassName was previously defined
  if((_myClass = NSClassFromString(aClassName)) == Nil)
     [NSException raise:@"InvalidClass" 
                 reason:@"Unknown class named %@.", aClassName);
  
  id myObj = [[_myClass alloc] init];
  [myObj whatever];

Re: nil, Nil, NULL, NSNull

#39
post #23

Earlier quoted context omitted.

He's not being sarcastic. Maybe a better example of what he is trying to get at is if (![missleLauncher isDisabled]) { /* declare thermonuclear war */ } When missleLauncher is nil, thermonuclear war is still declared which may not be the programmer's intent.

Properties and methods are given "positive" names as a matter of convention, and to make reasoning about Nil easier. In Objective-C, the question "should I name my method isEnabled or isDisabled?" has a reasonable answer - you consider what makes most sense (or any sense) when called on Nil. This is probably a good rule for other languages too - "negative" booleans can lead to double-negatives and unreadable code.

Even with a positive naming convention, you will have conditionals for the negative case, e.g. if (![str isEqualToString:@"myvalue"]) and falling into its block is not desirable when str is nil. Personally I have had plenty of bugs around things being unexpectedly nil, but I can't think of a case like this where I executed a block unexpectedly.

Re: nil, Nil, NULL, NSNull

#40
post #2

Good article overall. However, I must object to this bit: "C represents nothing as 0 for primitive value" That's not true. There is no "nothing" for integer types, and floats either also lack "nothing", or have NaN as their "nothing", depending on your perspective. One of the (many) annoying features of C-style NULL is that it means that some types are effectively option types while other types aren't, and there's no…

Definitely spot on regarding 0 not representing 'nothing'.

However, 'int *' is inherently "pointer to int or nothing" (in the same style as your NSString example), so I'm not sure I agree with your assertion that some types are option types while some aren't in C. Any type can be an option type (in your sense of the term, again a la your NSString example) by making it into a pointer.

Similarly, using an NSString without a pointer (which might not be possible in ObjC, but definitely possible for regular C/C++ objects) makes it not optional, like the 'int'.

Post reply on HN