• Mike (unregistered)

    At least the function in the first snippet's execution is faithful to its name...

  • Fuz (unregistered) in reply to Greg D
    Greg D:
    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.

    The C++ Standard says that dereferencing a null pointer is undefined behaviour. It does not result in a call with 'this == NULL'. It is not a seg fault. It does not 'work if it's not a virtual function'. It is not a corner of the language. It does not throw an exception. It is UNDEFINED.

    So could everyone please stop trying to define its behaviour. You're wrong. Your compiler may result in something which makes some kind of practical sense to you, but that's not the same as defining 'what it does', because there is no definition for what it does.

  • Someone who knows Java (unregistered) in reply to [twisti]
    [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, it tells the compiler which variant of an overridden method to use.

    Warning isn't a static J2SE class, so I'm going to assume that it's a JDialog subclass. JDialog has constructors that can take either a Dialog or a Frame as the parent window, and the caller is allowed to pass null for this parameter.

    However, if you pass null, the compiler has no way to determine which variant to use, because it relies on static typing for variant selection (all strongly-typed languages behave the same way). So the cast gives the compiler the information needed to disambiguate.

    An alternative would be:

    JFrame parent = null;
    Warning.showWarning(parent, ...
    
  • pafau k. (unregistered) in reply to [twisti]
    [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 ?

    It would actually work and is ignored on purpose by anyone who knows how compilers work.

    This would be actually NEEDED if there were more than one implementations of Warnig.showWarning, i.e:

    Warning.showWarning(JFrame f, String title, String msg); and Warning.showWarning(JDialog f, String title, String msg);

    Then, if you tried to simply call:

    Warning.showWarning(null, "", "");

    you'd get a compiler error along the line of "reference to showWarning is ambiguous , both methods apply".

  • (cs) in reply to [twisti]
    [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 ?

    You know, given that absolutely no one else has mentioned it yet in this thread, I thought I'd chime in here and say that this sort of cast would be necessary if there were multiple overloaded versions of showWarning that differed only in the type of the first parameter.

  • Andrew (unregistered) in reply to ObiWayneKenobi
    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.

    Actually, failIfNull() uselessly turns a NullPointerException into a RuntimeException. This must be a too-clever way to let worker threads report NullPointerException.

    As I recall, a Java thread can only catch its child (worker) threads RuntimeExceptions. So, it would make sense to change a "checked exception" into a RuntimeException, but NullPointerException is already a RuntimeException subclass.

    See: http://www.ibm.com/developerworks/java/library/j-jtp0924.html near "RuntimeException is the leading cause of thread death".

  • Nebu Pookins (unregistered) in reply to [twisti]
    [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 ?

    That's not a WTF. It's possible that the showWarning method is overloaded, e.g. with these signatures:

    public void showWarning(JFrame frame, String title, String msg);

    public void showWarning(JApplet frame, String title, String msg);

    If you were to make a call to:

    Warning.showWarning(null, title, msg);

    the compiler would not know which showWarning you were trying to call, hence the need for a cast.

  • endasil (unregistered) in reply to Andy
    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.

    Actually, it does exactly what it's supposed to do. It throws a RuntimeException if o is null. Granted, it does so a great deal sooner than the explicit "throw" statement is reached, and doesn't contain any of the error message. And as has been said, the method signature includes a throws clause which is in this case pointless.

    But other than that, this code is perfectly safe. It could be rewritten simply as this:

    public void failIfNull(Object o) {
      o.toString();
    }
  • endasil (unregistered) in reply to Andrew
    Andrew:
    Actually, failIfNull() uselessly turns a NullPointerException into a RuntimeException.

    No, it doesn't. It throws a NullPointerException long before the RuntimeException is created and thrown.

  • German B. (unregistered)

    I confess to having committed the same mistake as in failIfNull()... of course, that code never went beyond my development environment. It didn't take long to realize that was stupid. By the way, a minor additional WTF is that they (try to) throw RuntimeException instead of a more specific IllegalArgumentException.

  • fill'er'up (unregistered) in reply to StickyWidget

    That isNull code is a bit like checking if the car has run out of gasoline with a lighter in the gascap.

  • MntlChaos (unregistered) in reply to Andy

    Actually, it's not that surprising. In C++, if you have a non-virtual function, then nothing actually dereferences the implicit "this" object unless the code in your function does it. As a result, you don't get a crash until you try to actually access members inside the function. Putting the check for this == NULL at the top prevents this crash since you avoid dereferencing this if it's null.

    More to the situation at hand, it's not surprising that you'd have issues like that in DLL unloading, as that's when objects tend to become deleted, so you have an object deleted but are trying to do some cleanup on it anyway.

  • pdjohe (unregistered) in reply to [twisti]

    Granted the JFrame cast is pointless here, there are times that you should specifically cast a null to a type:

    public class VarargsNull {
    	public static void test(String... o) { }
    	public static void main(String... args) {
    		/* The next line gives compile-time warning: 
    		 * The argument of type null should explicitly be cast to String[] for 
    		 * the invocation of the varargs method test(String...) from type 
    		 * VarargsNull. It could alternatively be cast to String for a varargs 
    		 * invocation
    		 */
    		test(null);  
    		test((String[])null); // This is ok.
    		test((String)null);   // This is ok.
    	}
    }
    
  • Curtis (unregistered)

    Firstly:

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

    The null will be cast as a JFrame, but will still nonetheless be null. No difference really, in that an exception will still be thrown if you attempt to use the specified object.

    The main point though, and I must stress that this point is common to all software development and overridingly important, is that projects tend to get overcomplicated as a result of the desire to abstract functionality.

    As a software engineer with 15 years experience, the single most valuable insight I have to pass on to others, is: HARD CODE where it makes sense to do so. Yes, this goes against the grain a lot. However, it avoids many many problems. Take 'Enterprise' systems for example -- they are 98% glue, abstraction, obfuscation, and confusion. Is it better to call a factory method to instantiate a concrete subclass, or to call the subclass's constructor directly? (you save a lot of coding; and there's no chance of forgetting to update the factory after building your new class) Is it better to move all your SQL code to sprocs, resource files, or other obscure repositories -- or to hard code the query strings? (I can't think of very many reasons to use stored procs from app code...)

    The lesson here is that what most of us are supposed to be writing is business logic, not plumbing and associated crap. Enterprise frameworks which do this kind of ridiculous overkill are all well and good for astonishingly large systems; but everyone seems to a) overestimate the final size of the system (and thus overengineer it), and b) prefer writing wishy-washy boilerplate code instead of solving the actual problem at hand. Like premature optimization, over-enterprization is a programming sin of the most heinous order.

    Code should always reflect a balance between the need for reuse of functionality (genericity), and concrete, application-specific logic -- preferably implemented with the minimum of fuss and the maximum of clarity.

    Laziness is a virtue, and it's one that's practised religiously by the most effective software people at all times. Do your best to take the easy route wherever it makes sense to do so ( ... which is most of the time!)

  • Rob (unregistered) in reply to [twisti]

    No he's not. If this is null, null pointer exception. And this is in a class, so it's testing itself for null. It cannot be null if it's running ;-)

  • (cs) in reply to Andy
    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'd stick a breakpoint on the return statement, and when the breakpoint triggers, see what the backtrace looks like. If "this" is null, it usually means there's a howler of a WTF somewhere else in the program.

  • Gilhad (unregistered)

    When talking about NULLs - I found interesting fact, that in Pascal diagrams is possibility to construct syntactically valid command with dereferenced NULL (well nil in Pascal). Such as some_proc(some_type(nil^)); And better of all it even can be valid! The some_proc must have parameter of the some_type type, called by referrence. procedure some_proc(var X:some_type) Then the variable X contains not the value of the parameter given, but is pointed to the same location, where the parameter is stored. Which is nil (not defined place). And the procedure can then test the address of its local variable X and do something interesting after discovering, that the address of the X is nil (nowhere). In that case it cannot use the value of X ofcourse, but can use it as a marker, that the parameter was not filled.

    (Yes technically it is the same, as using some_func(null) if C++, with definition int some_func(char * X) but with much more funny/obfuscated style)

  • Fister (unregistered) in reply to Andy

    "this" is null each time you call a method on a NULL object pointer in most C++ implementations. If it's a virtual function, it'll crash before getting to the method (as there's no vtable), but if it's non-virtual, or called in non-virtual scope (constructor, explicitly qualified, etc) then you can totally call a member function on a NULL pointer. It only crashes if you try to then access some non-static member field or virtual function.

    The test for "this" as "null" was mostly WTF-ey because the code would do the same even if you didn't test for NULL.

  • Fister (unregistered) in reply to Curtis
    I can't think of very many reasons to use stored procs from app code.

    You mean, apart from performance? I've worked with databases that would auto-optimize schema and index physical layout for specific stored procedures. Also, anything that's not just a single query is likely to run better when there's not a round-trip for each cycle of an iteration (if you dare use those CURSORs...)

  • anon (unregistered) in reply to Andy

    Perhaps they wanted to throw an exception - any exception if something was null and that function conveniently did the job.

  • MDK (unregistered) in reply to StickyWidget

    Null has a type !

    When i was set to upgrade a ASP.NET/VB# project earlier this year, we had problems with Null not being cought by function overloads...

    the class had multiple helper functions like this

    //C# example public string helper(string s){ if(s==null) return ""; else return s; }

    however, some functions had to take care of Null, of 2 different types, DBNull and just Null.

    so it makes sense to actually pull out its type, and write that in an exception, if you want to know which type went Null...

    Captcha damnum

  • (cs) in reply to krupa
    krupa:
    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.

    It would segfault if the compilter dereferences p, but it doesn't. The compiler knows what class p is (its a myObject) so it compiles a jmp to the Print function in the vtable of myObject, passing in the value of p as the first argument. As long as the function doesn't make use of the "this" pointer everything will work just fine.

  • anonymous (unregistered) in reply to trollfun
    trollfun:
    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.

    Nope. I had to google for it.

    I'm in one of these 12-steps groups. We have to post in a forum each one of our small achievements to gain self-confidence ;)

  • Andrew (unregistered) in reply to [twisti]
    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

    Sometimes you need to do things like this if you've got two "Warning.showWarning(x, y, z)" methods that differ by their types. Like Warning.showWarning(JDialog, title, msg) and Warning.showWarning(JFrame, title, msg). If you pass null the compiler will complain about an ambiguous invocation. You actually need to cast the null. Weird, but there you go.

  • John, John Doe (unregistered) in reply to [twisti]

    He's casting null into a JFrame!

    Actually that must sometimes be used to disambiguate between polymorphic functions. Otherwise the compiler would complain that it doesn't know what exact function to invoke there.

  • Matthew Flint (unregistered) in reply to [twisti]
    [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 ?

    That's not the WFT - I've had to do it occasionally.

    If you had two methods void foo(String bar); void foo(Integer bar);

    and you wanted to call the first one with null parameter, then you would have to cast null, otherwise the compiler wouldn't know which method to call...

  • Timo (unregistered) in reply to [twisti]
    [twisti]:
    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 ?

    Casting null to a special type is sometimes necessary if the method call would otherwise be ambigous.

    For example, take the following two method signatures:

    void foo(a:Alpha) void foo(b:Beta)

    It's impossible to compile a call like foo(null). You have to cast null to one of the possible types.

  • Ikke (unregistered) in reply to snoofle
    snoofle:
    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)

    Why does this work then:

    class Blaat { private int x;

    public Blaat(int x)
    {
        this.x = x;
    }
    

    ] }

  • strategist333 (unregistered) in reply to StickyWidget

    Actually, the exception would get thrown at the this.equals(null) check, making it fail even more.

  • hgschmie (unregistered) in reply to [twisti]

    If you have two methods with different signatures, let's say foo(String x) and foo(Integer x) and you call foo(null), you will actually get an error at compile time (Ambiguous method invocation or something like this).

    Using foo((Integer)null) makes sure that the compiler selects the foo(Integer x) method. Nothing special here, just a hint to the compile, which method to use.

  • vrd (unregistered)

    this.equals(null) is not the same as this == null. this.equals is a method call that fails (null pointer exception) when this is null and then "if (this.equals(null))" cannot be true, so either you get a null pointer exception or you are in the else case. This is the same problem that StickyWidget showed.

  • AP (unregistered) in reply to [twisti]
    [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 ?

    The cast may be required. There may be overloaded versions of showWarning method (eg. showWarning(JFrame, String, String) and showWarning(JWindow, String, String)). The case indicates which version of the method is called.

  • Loren Pechtel (unregistered) in reply to Andy
    Andy:
    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.

    This is actually an example of the more general case for making reasonableness checks in incoming data. If such checks can be made inexpensively they are a good idea.

  • Vino (unregistered) in reply to Andy

    class CWhatever;

    int main() { CWhatever* pNew = NULL; pNew->DoSomething(); }

    class CWhatever { public: void DoSomething() { // this == NULL } };

    Dereferencing a NULL pointer to call a class method on it will give you what you described. That right there was probably your problem.

  • Vino (unregistered) in reply to Vino

    Also, props to me for not reading the thread :)

  • JavaCoder (unregistered) in reply to Andy
    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

    I agree.

    public void foo(String s) { if(s == null) throw new NullPointerException("Argument s can't be null!");

    PreparedStatement ps = .... ps.setString(1, s); ps.executeUpdate();

    ....

    if(s.length() > 5) { .... } PreapredStatement ps2 = ... ... ps2.executeUpdate(); }

    Putting the first if statement there is good form, because otherwise, the first PreparedStatement will execute, but the second PreparedStatment will not execute. Woops! Now the system is in an inconsistent state.

    But of course, the correct exception to throw for an illegal null, is a null pointer exception.


    Dental and prosthodontics in Beverly Hills

  • umm... (unregistered) in reply to Curtis

    Seventeen times. Seventeen separate times, people write about the need for passing (smth)null to facilitate overload-resolution. That's seventeen out of 86 posts, as I write this.

    Somewhere along the way, we get this little pearl of wisdom:

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

    The null will be cast as a JFrame, but will still nonetheless be null. No difference really, in that an exception will still be thrown if you attempt to use the specified object.

    No s***, sherlock - read much? Exactly who is using 'the specified object' now?

    If there's a lesson to be learned here, we can't say that it's in favor of well-documented code - seems too many people are averse to reading comments of any kind.

  • jj (unregistered) in reply to [twisti]

    dude, the cast is required to tell the compiler which 'showWarning' method should be used. There are several, one takes a jframe and one takes a jwindow if i remember correctly. So, it may look strange but it does work.

  • Aran (unregistered)
    this.equals(null)

    "Are you dead?"

    Questions that can be answered only one way.

  • (cs) in reply to ObiWayneKenobi
    ObiWayneKenobi:
    Hmm... the bigger issue, besides the shit code, is that the first one was written by a "senior developer".
    I think "senior" here has the same meaning as in "senior moment".
  • ajk (unregistered) in reply to Andy
    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. :)

    sounds like a great method you got there to track down bugs... maybe you can add your entry to wiki's anti-pattern article, they are lacking a bit of examples for their "Programming by Accident" article.

    http://en.wikipedia.org/wiki/Anti-pattern

  • leppie (unregistered)

    You sometime have to cast a null for overload resolution. Nothing funny about that.

  • Dave (unregistered) in reply to [twisti]

    Actually, casting a null to something concrete is perfectly valid. If you have overloaded methods, you'll have to do something like that.

    Now, the most hilarious problem is that [x].equals(null) will thros a NullPointerException every damn time [x] is actually null. Plus "this" can never be null! So it's a great big unnecessary test that fails in so many ways...

  • Dave (unregistered) in reply to Dave

    Heh - only just spotted that only "featured" comments were shown. Ignore my repetition of every damn sane point made in this thread.

  • Steve Holdoway (unregistered) in reply to Andy

    Aha! Defensive programming has been reinvented at last...

  • BillyBob (unregistered)

    Some gems I have come across which I'd like to share:

    something = NULL; something->hello();

    something = something_else; // stuff happens here something = NULL; delete something;

  • (cs)

    I have one to share, too. I found this one more than once, so it didn't seem to be an accident.

    if (s instanceof String && s != null)
    {
      //dosomething
    }
  • Mathias Ricken (unregistered) in reply to [twisti]

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

    No WTF there. Depending on the implementation of showWarning, this may work and may even be necessary.

    If you have two overloaded methods with the same name, for example

    void showWarning(JFrame frame, String title, String msg); void showWarning(JWindow frame, String title, String msg);

    then, if you want to pass null and this is an acceptable value, you need to use an explicit cast to tell the compiler which of the two methods to invoke. Otherwise, the method to invoke is ambiguous.

  • (cs)

    I think The Real WTF is that nobody has commented on the first call to showWarning() casting null to a JFrame.

  • Mathias Ricken (unregistered) in reply to BACON

    As stated many times, that can be necessary to remove ambiguity in the presence of method overloading.

    My personal WTF is that I had to write that explanation, even though several other readers had already pointed it out. I guess I need to learn how to click on the "All comments" link ;)

Leave a comment on “A Null Understanding”

Log In or post as a guest

Replying to comment #:

« Return to Article