Comment On A Null Understanding

These days, having written about bad code for a few years now, it's pretty rare to uncover a new anti-pattern like the FOR-CASE paradigm, IHBLRIA, or RLB o'PCC. However, having seen snippet after snippet like todays two, I think it's finally time to identify the Null Understanding... [expand full text]
« PrevPage 1 | Page 2 | Page 3Next »

Re: A Null Understanding

2007-12-14 08:03 • by mallard
Anyone else noticed that the forums (incl. Sidebar) are broken?

Re: A Null Understanding

2007-12-14 08:09 • by snoofle
166885 in reply to 166883
A) Some people should be legally barred from coding
B) re: sidebar: yeah, the links are still pointing at the now defunct worsethanfailure.com

Re: A Null Understanding

2007-12-14 08:26 • by Jeremy (unregistered)
I actually had to read that second one three times before I believed that someone could be that unbelievably stupid!!

Re: A Null Understanding

2007-12-14 08:28 • by Grobbendonk (unregistered)
The second one was from Northern Rock

Re: A Null Understanding

2007-12-14 08:29 • by sarge (unregistered)
The first one made me laugh.
The second one frightened me!

Re: A Null Understanding

2007-12-14 08:30 • by dkf (unregistered)
The first one is a bone-headed programmer WTF (Java's supposed to work out the class of the 'null' exactly how?) but the second is more interesting. It's possibly not a WTF of the programmer of that code; it could be that the Warning class has two overloaded methods where the first argument can be one of several types. On the other hand, that then makes the Warning class itself the WTF if it treats 'null' differently according to which route it came through. I can totally believe that being the case...

Re: A Null Understanding

2007-12-14 08:31 • by djork
I have come across LOTS of code in my project that follows the I-Hope-I'm-Not-Null pattern:


if (this != null)
{
...
}

Re: A Null Understanding

2007-12-14 08:31 • by Anonymous Coward (unregistered)
AHHHHHHHH MY EYES!!!!!!!!

Re: A Null Understanding

2007-12-14 08:32 • by ObiWayneKenobi
Hmm... the bigger issue, besides the shit code, is that the first one was written by a "senior developer". I would imagine a senior developer to know better, but then again this IS the Daily WTF, and most of the snippets/evil stuff here was written by "senior" developers.

Re: A Null Understanding

2007-12-14 08:35 • by Matthew (unregistered)
166893 in reply to 166889
this.equals(null)
is still a bit suspect though!

OK, you could override equals() so that returns true in some cases. But why would you?

Re: A Null Understanding

2007-12-14 08:35 • by Sunstorm
I'm not sure if I understand the WTFiness of the first one, since I'm not versed in how Java treats nulls. Is the WTF that Java would already throw an exception on it's own if you access a null?

Re: A Null Understanding

2007-12-14 08:38 • by djork
166895 in reply to 166892
Hmm... the bigger issue, besides the shit code, is that the first one was written by a "senior developer". I would imagine a senior developer to know better, but then again this IS the Daily WTF, and most of the snippets/evil stuff here was written by "senior" developers.


Apologies for posting a JPEG of a book's text, but I think that this excerpt is relevant.

Re: A Null Understanding

2007-12-14 08:48 • by JQ (unregistered)
The system I'm developing is written in a language that implicitly returns null in case nothing is returned explicitly. Thus, it makes perfect sense to use following pattern on a regular basis, because otherwise an implicit return null (caution: very dangerous) would happen without warning:


method foo.bar()
# do some processing
if a isnt null
then
return a
endif
endmethod


The code was riddled with variations of such a construct. There was an even more explicit version:


method foo.bar()
# do some processing
if a isnt null
then
return a
else
return null
endif
endmethod


It took a while to eliminate every single instance of such nonsense with this functionally equivalent construct:


method foo.bar()
# do some processing
return a
endmethod

Re: A Null Understanding

2007-12-14 08:52 • by anon (unregistered)
Is this a Java thing? I get you'd never design a system this way yourself, but what if they are interacting with a third party library in C++ that returns pointers? One would expect that you'd check to see that a pointer returned isn't NULL before it's dereferenced.

If the fact that the pointer is NULL is a failing case anyway, then failIfNull() collapses four physical lines of code down to one, and eliminates a layer of indirection. If you're making a dozen calls in a row into this library then failIfNull() eliminates a lot of redundant code.

Re: A Null Understanding

2007-12-14 08:52 • by snoofle
166899 in reply to 166894
Sunstorm:
I'm not sure if I understand the WTFiness of the first one, since I'm not versed in how Java treats nulls. Is the WTF that Java would already throw an exception on it's own if you access a null?

In Java, if something is "null", it can not be dereferenced. As such, assuming x is null: x.getClass() in and of itself will throw a NullPointerException. The coder tested to see if something was null, and then dereferenced the known null object in a vain and misguided attempt to identify it.

Re: A Null Understanding

2007-12-14 08:54 • by jLoyd (unregistered)
166900 in reply to 166894
Sunstorm:
I'm not sure if I understand the WTFiness of the first one, since I'm not versed in how Java treats nulls. Is the WTF that Java would already throw an exception on it's own if you access a null?


Mostly correct. o.getClass() will throw a null pointer exception b/c 'o' is null.

Re: A Null Understanding

2007-12-14 08:56 • by snoofle
166902 in reply to 166898
anon:
Is this a Java thing? I get you'd never design a system this way yourself, but what if they are interacting with a third party library in C++ that returns pointers? One would expect that you'd check to see that a pointer returned isn't NULL before it's dereferenced.

If the fact that the pointer is NULL is a failing case anyway, then failIfNull() collapses four physical lines of code down to one, and eliminates a layer of indirection. If you're making a dozen calls in a row into this library then failIfNull() eliminates a lot of redundant code.

The WTF wasn't the function to encapsulate handling a null-check so much as it was dereferencing a known null pointer!

Re: A Null Understanding

2007-12-14 08:59 • by [twisti] (unregistered)
166903 in reply to 166883
One of the best parts of the article got completely ignore by all commenters!

Warning.showWarning((JFrame) null, title, msg);

He's casting null into a JFrame! It really makes you wonder what that would do if it would actually work ... create a special null that isn't actually null but an empty JFrame ?

Re: A Null Understanding

2007-12-14 09:01 • by Chris (unregistered)
166905 in reply to 166898
anon:
Is this a Java thing? I get you'd never design a system this way yourself, but what if they are interacting with a third party library in C++ that returns pointers? One would expect that you'd check to see that a pointer returned isn't NULL before it's dereferenced.

If the fact that the pointer is NULL is a failing case anyway, then failIfNull() collapses four physical lines of code down to one, and eliminates a layer of indirection. If you're making a dozen calls in a row into this library then failIfNull() eliminates a lot of redundant code.


The first one is a WTF because Java will throw a subclass of RuntimeException called NullPointerException if an attempt to dereference a null is made. The code attempts to dereference a null, having already established it's null, which results in a NullPointerException anyway - not the plain RuntimeException that the programmer tried to construct.

As for the second one, it's utterly redundant. You cannot call a method on yourself until you're constructed. Even calling a method on itself from the objects constructor wont result in "this" being null.

Re: A Null Understanding

2007-12-14 09:01 • by Andy (unregistered)
166906 in reply to 166890
So, strangely enough, I've seen places where that was needed.

In a C++ DLL I was working on there was this weird race condition happening during the unloading of the DLL, and one of the methods would occasionally crash. When walking through it with the debugger I found that the crash happened because `this` was equal to NULL. I never managed to find the root cause of the problem, but just putting

`if(this == NULL) { return; }

at the top of the function fixed the crash. Since it was happening when the DLL was being unloaded and the results of that function weren't really important anymore we decided it wasn't worth killing ourselves trying to find the root cause anymore.

Fortunately, my current project is to rewrite that entire DLL (mainly triggered by Vista incompatibilities. Thanks Vista!), so hopefully I'll be able to avoid that this time. :)

Re: A Null Understanding

2007-12-14 09:02 • by pscs
166908 in reply to 166903
[twisti]:
One of the best parts of the article got completely ignore by all commenters!

Warning.showWarning((JFrame) null, title, msg);

He's casting null into a JFrame! It really makes you wonder what that would do if it would actually work ... create a special null that isn't actually null but an empty JFrame ?


I don't know enough about 'showWarning', but in the Windows SDK, 'MessageBox' is passed a window handle as the first parameter if you want the MessageBox to be the child of another window, or you pass 'NULL' if you want it not to be a child window of anything.

I'd guess that it's possibly the same here.

Re: A Null Understanding

2007-12-14 09:02 • by anonym (unregistered)
166909 in reply to 166894
Yes, both snippets invoke methods on null objects. You cannot invoke a method in a null object, java throws a NullPointerException :)

Re: A Null Understanding

2007-12-14 09:04 • by Chris (unregistered)
166910 in reply to 166903
[twisti]:
One of the best parts of the article got completely ignore by all commenters!

Warning.showWarning((JFrame) null, title, msg);

He's casting null into a JFrame! It really makes you wonder what that would do if it would actually work ... create a special null that isn't actually null but an empty JFrame ?


If the Warning class is modelled on JOptionPane, then the cast is probably ensuring a call to showWarning(JFrame f, ...) rather than showWarning(JDialog d, ...). Without the cast it wouldn't even compile, as the compiler hasn't enough information to determine which method to call.

Re: A Null Understanding

2007-12-14 09:05 • by pscs
166911 in reply to 166883
mallard:
Anyone else noticed that the forums (incl. Sidebar) are broken?


It looks like it's the DNS entry for 'forums.worsethanfailure.com' which got lost sometime yesterday, and then got re-instated. But the negative TTL is 1 day on the worsethanfailure.com domain, so your DNS server is remembering that 'forums.' doesn't exist, even though it now does.

Add
74.50.106.245 forums.worsethanfailure.com
to your hosts file (or wait a day for the negative TTL to expire)

Re: A Null Understanding

2007-12-14 09:06 • by trollfun (unregistered)
166912 in reply to 166909
anonym:
Yes, both snippets invoke methods on null objects. You cannot invoke a method in a null object, java throws a NullPointerException :)

Wow. Did you figured that out all by yourself or did you have to google for it.

Re: A Null Understanding

2007-12-14 09:09 • by Andy (unregistered)
166913 in reply to 166905
Chris:

The first one is a WTF because Java will throw a subclass of RuntimeException called NullPointerException if an attempt to dereference a null is made.


Actually, I've found doing some quick checks for null at the top of a function and explicitly throwing an exception if they're null is a good thing. While it's true that Java will throw a NullPointerException when dereferencing a null, by doing the check at the beginning of the function and throwing there, you prevent the possibility of getting partway through your processing (and possibly changing some class state) and then causing the exception. Failing fast is almost always better.

That said, the check done in that first one is totally broken anyway, as it's dereferencing the null when trying to generate the exception.

Re: A Null Understanding

2007-12-14 09:11 • by Andy (unregistered)
166914 in reply to 166908
pscs:
[twisti]:
One of the best parts of the article got completely ignore by all commenters!

Warning.showWarning((JFrame) null, title, msg);

He's casting null into a JFrame! It really makes you wonder what that would do if it would actually work ... create a special null that isn't actually null but an empty JFrame ?


I don't know enough about 'showWarning', but in the Windows SDK, 'MessageBox' is passed a window handle as the first parameter if you want the MessageBox to be the child of another window, or you pass 'NULL' if you want it not to be a child window of anything.

I'd guess that it's possibly the same here.


It's probably to remove ambiguity. Warning.showWarning probably has multiple signatures, with the only difference being the type of the first argument. When you pass 'null' explicitly (as opposed to a variable that's set to null) the compiler doesn't know the type, so it can't determine which version of the method to call. By casting it to a JFrame the compiler knows which showWarning() method to call.

Re: A Null Understanding

2007-12-14 09:13 • by pscs
166915 in reply to 166905
Chris:
As for the second one, it's utterly redundant. You cannot call a method on yourself until you're constructed. Even calling a method on itself from the objects constructor wont result in "this" being null.


Ah, but it ain't necessarily so (at least in C++)

---------
#include <stdio.h>

class myObject
{
public:
void Print(void)
{
printf("0x%08lx\n", this);
}
};

myObject *foo()
{
return NULL;
}

int main()
{
myObject *p = foo();
p->Print();
}
----------

Here the 'Print' object will be called on an object whose 'this' pointer is NULL, so it'll print out '0x00000000'

Re: A Null Understanding

2007-12-14 09:21 • by [twisti] (unregistered)
166916 in reply to 166914
Andy:
pscs:
[twisti]:
One of the best parts of the article got completely ignore by all commenters!

Warning.showWarning((JFrame) null, title, msg);

He's casting null into a JFrame! It really makes you wonder what that would do if it would actually work ... create a special null that isn't actually null but an empty JFrame ?


I don't know enough about 'showWarning', but in the Windows SDK, 'MessageBox' is passed a window handle as the first parameter if you want the MessageBox to be the child of another window, or you pass 'NULL' if you want it not to be a child window of anything.

I'd guess that it's possibly the same here.


It's probably to remove ambiguity. Warning.showWarning probably has multiple signatures, with the only difference being the type of the first argument. When you pass 'null' explicitly (as opposed to a variable that's set to null) the compiler doesn't know the type, so it can't determine which version of the method to call. By casting it to a JFrame the compiler knows which showWarning() method to call.


Yeah, I was already reminded about that on IRC. I guess today I'm the real WTF (tm).

Re: A Null Understanding

2007-12-14 09:22 • by bryan986
You know what happens when you abuse something, it gets taken away! No more null for you!

Re: A Null Understanding

2007-12-14 09:23 • by krupa (unregistered)
166918 in reply to 166915
pscs:
Chris:
As for the second one, it's utterly redundant. You cannot call a method on yourself until you're constructed. Even calling a method on itself from the objects constructor wont result in "this" being null.


Ah, but it ain't necessarily so (at least in C++)

---------
#include <stdio.h>

class myObject
{
public:
void Print(void)
{
printf("0x%08lx\n", this);
}
};

myObject *foo()
{
return NULL;
}

int main()
{
myObject *p = foo();
p->Print();
}
----------

Here the 'Print' object will be called on an object whose 'this' pointer is NULL, so it'll print out '0x00000000'


I can't tell if you're serious about this or not. foo() returns NULL, so p is null, so p->Print() is a seg. fault.

Re: A Null Understanding

2007-12-14 09:28 • by Sunday Ironfoot
166919 in reply to 166890
djork:
I have come across LOTS of code in my project that follows the I-Hope-I'm-Not-Null pattern:


if (this != null)
{
...
}


That code raises an interesting paradox (if that's the right word), because the code would be executing within the scope of that object, so if it were to be null then that code wouldn't exist, so it's checking if itself exists, but if it didn't exist, there would be nothing being checked...ARRHHH!! MY HEAD!!!!!!!!!

Re: A Null Understanding

2007-12-14 09:28 • by krupa (unregistered)
166920 in reply to 166918
krupa:

I can't tell if you're serious about this or not. foo() returns NULL, so p is null, so p->Print() is a seg. fault.


OOPS, I take that back. That actually does work.

Re: A Null Understanding

2007-12-14 09:40 • by Volmarias
Ugh. This is the first time in a while I've actually placed my head into my hands and groaned after looking at code.

Re: A Null Understanding

2007-12-14 09:48 • by dkf (unregistered)
166924 in reply to 166920
krupa:
krupa:

I can't tell if you're serious about this or not. foo() returns NULL, so p is null, so p->Print() is a seg. fault.
OOPS, I take that back. That actually does work.
But it wouldn't work if the method was virtual. In Java, all non-static methods are virtual (i.e. resolved according to the real object type).

The fact that is this works in C++ is today's Real WTF?!

Re: A Null Understanding

2007-12-14 09:51 • by fanguad (unregistered)
On the project I'm working on we have a design constraint of "no Null Pointer Exceptions... ever". So we understand well the value of nulls... (code summary, not actual code)


String name = retrieveName(object);
if (name == null) {
log.warn("object name was null");
} else {
...
}

...

String retrieveName(MyObjectWrapper object) {
String retVal = object.getName();
if (retVal == null) {
log.warn("object retrieveName was null");
}
}

...

class MyObject {
String getName() {
if (this.name == null) {
log.warn("getName returned null");
}
return this.name;
}
}


PS: that was sarcasm. still, I'd rather have this than the article's code

Re: A Null Understanding

2007-12-14 09:54 • by Rene (unregistered)
166926 in reply to 166924
dkf:
krupa:
krupa:

I can't tell if you're serious about this or not. foo() returns NULL, so p is null, so p->Print() is a seg. fault.
OOPS, I take that back. That actually does work.
But it wouldn't work if the method was virtual. In Java, all non-static methods are virtual (i.e. resolved according to the real object type).

The fact that is this works in C++ is today's Real WTF?!


This works in C++ because a non-virtual member function is effectively just a C function with a mangled name and a hidden parameter passed in (the this pointer). Thus it won't know it's being called on a null object until it tries to dereference this. In the virtual case it immediately has to do so in order to look up the function in the vtable, thus immediate segfault. Not really a WTF, just an implementation detail imo.

Re: A Null Understanding

2007-12-14 10:00 • by StickyWidget (unregistered)
166927 in reply to 166906
That's not the problem, the problem is the "o.getClass().getName()" snippet. If "o" is Null, then you'll get a NullPointerException thrown, and you'll never get any value for the class name.

Luckily for this joker, a NullPointerException is a subtype of RuntimeException, so everything still works. If he had set it to throw some other kind of exception, he'd be in trouble, as the NullPointerException would crash the whole thing. He'll also never know what class happened to be null.

~Sticky

Re: A Null Understanding

2007-12-14 10:01 • by snoofle
166928 in reply to 166915
pscs:
Chris:
As for the second one, it's utterly redundant. You cannot call a method on yourself until you're constructed. Even calling a method on itself from the objects constructor wont result in "this" being null.


Ah, but it ain't necessarily so (at least in C++)

---------
#include <stdio.h>

class myObject
{
public:
void Print(void)
{
printf("0x%08lx\n", this);
}
};

myObject *foo()
{
return NULL;
}

int main()
{
myObject *p = foo();
p->Print();
}
----------

Here the 'Print' object will be called on an object whose 'this' pointer is NULL, so it'll print out '0x00000000'


Ahhh, the semantics of object construction. For the uninitiated, "this" technically doesn't exist until after the constructor completes execution (at least in C++ and Java)

Re: A Null Understanding

2007-12-14 10:04 • by Greg D (unregistered)
166929 in reply to 166918
krupa:
pscs:


Ah, but it ain't necessarily so (at least in C++)

---------
#include <stdio.h>

class myObject
{
public:
void Print(void)
{
printf("0x%08lx\n", this);
}
};

myObject *foo()
{
return NULL;
}

int main()
{
myObject *p = foo();
p->Print();
}
----------

Here the 'Print' object will be called on an object whose 'this' pointer is NULL, so it'll print out '0x00000000'


I can't tell if you're serious about this or not. foo() returns NULL, so p is null, so p->Print() is a seg. fault.

As I was reminded by one of my co-workers today, p->Print() won't fail if Print() is a non virtual member of myObject and if this is not dereferenced in Print(). It's related to the corner of the language that makes

delete this;
legal and defined, if not entirely kosher.

Re: A Null Understanding

2007-12-14 10:06 • by charles bretana (unregistered)
166930 in reply to 166923
Isn't the wtf that in the block of code that only runs if o is null, he's USING o, and attempting to access a property of o ???

Re: A Null Understanding

2007-12-14 10:10 • by dlikhten
166932 in reply to 166913
Andy:
So, strangely enough, I've seen places where that was needed.

In a C++ DLL I was working on there was this weird race condition happening during the unloading of the DLL, and one of the methods would occasionally crash. When walking through it with the debugger I found that the crash happened because `this` was equal to NULL. I never managed to find the root cause of the problem, but just putting

`if(this == NULL) { return; }

at the top of the function fixed the crash. Since it was happening when the DLL was being unloaded and the results of that function weren't really important anymore we decided it wasn't worth killing ourselves trying to find the root cause anymore.

Fortunately, my current project is to rewrite that entire DLL (mainly triggered by Vista incompatibilities. Thanks Vista!), so hopefully I'll be able to avoid that this time. :)


I think you are missing the point...
this.equals(null) implies that this is not null. Had they had remotely a condition like what you describe the code would have been:

// This check is because of a race condition that occurres when XYZ happens.
if(this == null)
{
// handle
}

{notice the comment :) )

Re: A Null Understanding

2007-12-14 10:28 • by tchize
166940 in reply to 166903
[twisti]:
One of the best parts of the article got completely ignore by all commenters!

Warning.showWarning((JFrame) null, title, msg);

He's casting null into a JFrame! It really makes you wonder what that would do if it would actually work ... create a special null that isn't actually null but an empty JFrame ?

Actually, that might be the only part of code that is correct!

Warning.showWarning(JButton, String, String)
Warning.showWarning(JFrame, String, String)

Typecast of null is mandatory :)

Re: A Null Understanding

2007-12-14 10:52 • by Carl Johan (unregistered)
Senior doesn't necessarily mean experienced or knowledgable.

Re: A Null Understanding

2007-12-14 11:08 • by Virtua1 (unregistered)
166954 in reply to 166903
Ever heard about method overloading.
There might be 2 show warning methods with 3 params.

showWarning(JFrame frame, String title, String msg);
Warning.showWarning(JDialog dialog, String title, String msg);

The cast is needed to specify which of both methods needs to be invoked.

Re: A Null Understanding

2007-12-14 11:09 • by Paul (unregistered)
166955 in reply to 166894
No, the WTF is that in Java you don't have to declare a RuntimeException.

Re: A Null Understanding

2007-12-14 11:15 • by Chemisor
The failIfNull-type function can actually be quite useful in C++. Because throwing an exception generates a boatload of code, you can considerably reduce your code size by replacing a dozen similar throws with a call to a function that throws.

Re: A Null Understanding

2007-12-14 11:34 • by hunter9000
Even if the second snippet wasn't dereferencing a null reference, it's still useless. All he'd get was the name of the class the reference points to, not the name of the variable.
        Object o = new Object();

System.out.println(o.getClass().getName());
o = new String("hello");
System.out.println(o.getClass().getName());

Prints out:
java.lang.Object

java.lang.String

Awesome! java.lang.String is null! That's real helpful. He'll still have to follow the stack trace to find out which variable is null.

Re: A Null Understanding

2007-12-14 11:39 • by punissuer
166962 in reply to 166927
StickyWidget:
Luckily for this joker, a NullPointerException is a subtype of RuntimeException, so everything still works. If he had set it to throw some other kind of exception, he'd be in trouble, as the NullPointerException would crash the whole thing.
Actually, RuntimeException is an "unchecked" exception in Java, which means it (and its subclass exceptions like NullPointerException) can be thrown by any method, even those which don't declare they throw any exceptions at all. If all exceptions were checked by the compiler, then the compiler would have to require any method which dereferences a reference (or calls another method which does this) to declare that it can throw NullPointerExceptions. They're so common we just call them NPE's.

Re: A Null Understanding

2007-12-14 11:46 • by It's a Feature
166963 in reply to 166913
Andy:

...
That said, the check done in that first one is totally broken anyway, as it's dereferencing the null when trying to generate the exception.


And that's the real WTF of the first one. If the object is null, how can you expect to run a method on it?
« PrevPage 1 | Page 2 | Page 3Next »

Add Comment