Live data from Hacker News

nil, Nil, NULL, NSNull

nshipster.com

61–66 of 66 posts

Re: nil, Nil, NULL, NSNull

#61
post #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…

No! C and C++ are define NULL identically: it can be either 0 or (void * ) 0 at the discretion of the compiler author.

So the bug you mention which bit you by using "C library from C++" was not caused by a difference between C and C++. It was caused by a difference in the definition of NULL between those two compilers. You could just as easily have found a C++ compiler which did work, or a C compiler which didn't.

Re: nil, Nil, NULL, NSNull

#62

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 the…

Null is great.

Null as a valid value for every reference type by default is brain-dead.

It is one of my major gripes with modern C#.

Re: nil, Nil, NULL, NSNull

#63
post #17

Earlier quoted context omitted.

A container might have an isEmpty function, and if the pointer is nil, that is probably more empty than not empty (though personally I don't believe either answer makes sense). "[x isEmpty]" might be more appropriate than "[x count]==0" for a list-type container. I always check for nil explicitly, personally. It sidesteps any question of whether the method makes sense in the nil case. And sending messages to nil can'…

Cheers for the counter-example. I agree there isn't really a sensible answer for [nil isEmpty]. There are two uses of isEmpty I can think of. if ([container isEmpty]) { [container addItem:item]; } We want to add an item to an empty container. If it's nil, we don't add an item to it; that seems okay. if (![container isEmpty]) { Item item = [container getItemAt:0]; [item doSomething]; } We check there will be an item b…

NSArray has a constant-time size query, so you might as well do "[x count]==0". If you had a linked list type structure, though, you might just have next/prev pointers in your list object, making a size query an O(N) operation. (The C++ STL provides an "empty()" function in its containers for presumably this reason. It has some containers that have to be implemented as linked lists or trees, meaning there's the possibility that "x.empty()" to be much more efficient than "x.size()==0". Not sure how often implementations take advantage of this, mind.)

As for how you'd use it, I've pretty much always used it for early outs:

    if(items.empty()) return NULL;
    return &items[items.size()%rand()];
or for filling in caches:

    if(items.empty()) return NULL;

    if(cache.empty()) { /* fill cache */ }

    assert(cache[index].underlying_item==items[index]);
    return cache[index].some_other_data;
So it always ends up being tested positively. Or it does if you code like me, anyway :) (I make no statement about whether you should or not.)

Re: nil, Nil, NULL, NSNull

#64
post #61
post #37

Earlier quoted context omitted.

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…

No! C and C++ are define NULL identically: it can be either 0 or (void * ) 0 at the discretion of the compiler author. So the bug you mention which bit you by using "C library from C++" was not caused by a difference between C and C++. It was caused by a difference in the definition of NULL between those two compilers. You could just as easily have found a C++ compiler which did work, or a C compiler which didn't.

If you think a C++ compiler has the option to define NULL as ((void * ) 0) then all I ask is that you simply try it yourself and let me know what compiler error you get. Make sure to turn off permissive flags.

    class Foo { };
    int main() {
        Foo *foo = malloc(sizeof(Foo)); // returns void*
    }

Re: nil, Nil, NULL, NSNull

#65
post #64
post #61

Earlier quoted context omitted.

No! C and C++ are define NULL identically: it can be either 0 or (void * ) 0 at the discretion of the compiler author. So the bug you mention which bit you by using "C library from C++" was not caused by a difference between C and C++. It was caused by a difference in the definition of NULL between those two compilers. You could just as easily have found a C++ compiler which did work, or a C compiler which didn't.

If you think a C++ compiler has the option to define NULL as ((void * ) 0) then all I ask is that you simply try it yourself and let me know what compiler error you get. Make sure to turn off permissive flags. class Foo { }; int main() { Foo *foo = malloc(sizeof(Foo)); // returns void* }

You are confusing the preprocessor #define named NULL with the null pointer. Your code example involves void pointers, which is yet a third thing.

Re: nil, Nil, NULL, NSNull

#66
post #65
post #64

Earlier quoted context omitted.

If you think a C++ compiler has the option to define NULL as ((void * ) 0) then all I ask is that you simply try it yourself and let me know what compiler error you get. Make sure to turn off permissive flags. class Foo { }; int main() { Foo *foo = malloc(sizeof(Foo)); // returns void* }

You are confusing the preprocessor #define named NULL with the null pointer. Your code example involves void pointers, which is yet a third thing.

That's because NULL is the pre-processor define. The null pointer itself has no name in C or C++ (pre-11), except that the language will convert integer '0' into whatever the hardware's null pointer is (usually also 0) when converting integral types to pointer types. C++11 added a name and specific type for the null pointer but that's about it.
Post reply on HN