But...Anything Can Happen!

« Return to Article
  • Doo-doo Facial Hair 2012-11-14 08:07
    I just got terrible Excel flashbacks of functions with endless =IF(something;"OK";IF(something;"LESS OK";IF(something;"HELP SOS";IF(something;"NO WAIT IT'S OK";IF(etc...

    And yes I know I was using Excel for something it was not really meant for but it was the only programming tool available (read: allowed) at the time.

  • ACK 2012-11-14 08:12
    Damn, waited for years to write "First"... *Went to check my else if branch code for bugs*
  • Mr Magoo 2012-11-14 08:12
    anything can be frist
  • William F 2012-11-14 08:13
    TRWTF is the happy ending. Bad developer gets fired?

    Since this is in a safety critical industry, I feel better about airplanes and self driving cars already.

    CAPTCHA: ague - what I get from some of these stories
  • Michael P 2012-11-14 08:15
    Some coding standards (like, say, the ones used for C++ on the US Joint Strike Fighter program) specifically require an if/else if chain to be terminated with either an "else" handler or a comment that explains why there is no else. That seems like good practice for any software with significant safety implications.
  • Tom 2012-11-14 08:22
    Michael P:
    if/else if chain to be terminated with either an "else" handler or a comment that explains why there is no else
    How about

    else
    {
    alert('Universe asplode, select a different quantum fork');
    }

    Should be as good as the comment, if not better.
  • Rodnas 2012-11-14 08:25
    // DO NOT make changes below this comment

    if (frist) {
    doLameFristComment();
    } else if (!frist) {
    doAnythingCanHappenComment("And probably will!");
    }
  • LoremIpsumDolorSitAmet 2012-11-14 08:26
    by creating code paths that did not assign these variables, he would cause unpredictable behavior depending on the prior values of the variables

    I don't understand this. Where are these new code paths? Is he talking about the possibility of some variable being undefined and therefore the IF and the ELSE IF both eval to false and neither block is executed?

    If so, TRWTF is using a loosely typed run-time language like JavaScript or PHP that allow undefined variables... especially in life-critical apps.

    Or, more likely, I've been mislead by Alex's brillant editing.
  • Anonymous Will 2012-11-14 08:37
    I think he means about when some variable is supposed to be assigned a different value in the 2 branches.
  • Karl 2012-11-14 08:41
    Tom:
    alert('Universe asplode, select a different quantum fork');
    Oh, come on! We can do better than that.

    How about:

    alert("Logic inconsistency error detected! After you click OK, this instance of the simulation will be terminated. You should awake in a similar universe where this never happened. In most cases people report no recollection of this event.\n\nOh by the way, if you tell anyone else, it makes timeline reintegration much more difficult. So don't do that.");
  • long johnson 2012-11-14 08:43
    if patient.sick? && !patient.dead?
    heal patient
    else if !patient.sick? && !patient.dead?
    bury patient
    end
  • Anketam 2012-11-14 08:46
    Wow the process worked.
  • Justsomedudette 2012-11-14 08:46
    LoremIpsumDolorSitAmet:

    If so, TRWTF is using a loosely typed run-time language like JavaScript or PHP that allow undefined variables... especially in life-critical apps.

    Or, more likely, I've been mislead by Alex's brillant editing.
    That would be Mark's brilliant editing, but please don't let accuracy or spelling ruin a perfectly snide comment.
  • Andrew 2012-11-14 08:47
    You're right, anything could happen:
    a = 10
  • TGV 2012-11-14 08:47
    if patient.sick? && !patient.dead?
    heal patient
    else if !patient.sick? || patient.dead?
    if patient.dead?
    bury patient
    end
    end

    FTFY
  • Herwig 2012-11-14 08:52

    if (a)
    {
    doSomething();
    }
    else if (!a)
    {
    doSomethingElse();
    }
    else
    {
    gotoTRWTF();
    }
  • LoremIpsumDolorSitAmet 2012-11-14 08:55
    Justsomedudette:
    LoremIpsumDolorSitAmet:

    If so, TRWTF is using a loosely typed run-time language like JavaScript or PHP that allow undefined variables... especially in life-critical apps.

    Or, more likely, I've been mislead by Alex's brillant editing.
    That would be Mark's brilliant editing, but please don't let accuracy or spelling ruin a perfectly snide comment.

    Just because Mark submitted it doesn't mean it didn't get preprocessed by the almighty Alex! Or maybe Mark is his sockpuppet. Or maybe they're just as brillant as each other.

    PS. 'brillant' is not a typo; you must be new here!
  • Anonymous Cow 2012-11-14 08:55
    LoremIpsumDolorSitAmet:
    I don't understand this. Where are these new code paths? Is he talking about the possibility of some variable being undefined and therefore the IF and the ELSE IF both eval to false and neither block is executed?

    The issue that they're referring to would come up if they changed this:

    if(a > 10)
    
    printf("It's so big!");
    else
    printf("Not so big... :(");


    ...into this:

    if(a > 10)
    
    printf("It's so big!");
    else if(a < 10)
    printf("Not so big... :(");


    What happens if a is 10?
  • masseyis 2012-11-14 08:56
    ACK:
    Damn, waited for years to write "First"... *Went to check my else if branch code for bugs*


    Decades of experience in waiting to be frist
  • stinkiemcslimey 2012-11-14 09:04
    if (a)
    {
    dowork();
    } else if (!a) {
    domorework();
    } else {
    return(FILE_NOT_FOUND);
    }
  • LoremIpsumDolorSitAmet 2012-11-14 09:07
    Anonymous Cow:
    LoremIpsumDolorSitAmet:
    I don't understand this. Where are these new code paths? Is he talking about the possibility of some variable being undefined and therefore the IF and the ELSE IF both eval to false and neither block is executed?

    The issue that they're referring to would come up if they changed this:

    if(a > 10)
    
    printf("It's so big!");
    else
    printf("Not so big... :(");


    ...into this:

    if(a > 10)
    
    printf("It's so big!");
    else if(a < 10)
    printf("Not so big... :(");


    What happens if a is 10?

    Yes, I understand how the terrible reverse-ifs resulted in "no fewer than ten bugs [being] created in the process".

    But that doesn't help me understand "creating code paths that did not assign these variables".
  • Mike 2012-11-14 09:09
    shouldn't it be
    ...
    else if !patient.sick? || patient.dead?
    ...
  • Matthew 2012-11-14 09:13
    int foo;
    
    if (a > 10) {
    foo = 1;
    }
    else if (a < 10) {
    foo = 2;
    }
    printf("%d\n", foo); // Anything can happen
  • Ben Jammin 2012-11-14 09:16
    Mike:
    shouldn't it be
    ...
    else if !patient.sick? || patient.dead?
    ...

    ...no fewer than ten bugs were created in the process.

    Think about it... then giggle.
  • Kaso 2012-11-14 09:19

    char* ptr;

    if (something > 10) {
    ptr = BIG_BUFFER;
    } else if (something < 10) {
    ptr = SMALL_BUFFER;
    }

    memcpy(ptr, source, n); //error as the code path we followed did not assign ptr
  • Ben Jammin 2012-11-14 09:21
    Mike:
    shouldn't it be
    ...
    else if !patient.sick? || patient.dead?
    ...

    Plus, if you're not sick, hopefully being buried isn't the solution. Obviously, patient.sick? needs to be a tri-state boolean of true, false, and LIFE_NOT_FOUND.
  • Max 2012-11-14 09:23
    LoremIpsumDolorSitAmet:
    Anonymous Cow:
    LoremIpsumDolorSitAmet:
    I don't understand this. Where are these new code paths? Is he talking about the possibility of some variable being undefined and therefore the IF and the ELSE IF both eval to false and neither block is executed?

    The issue that they're referring to would come up if they changed this:

    if(a > 10)
    
    printf("It's so big!");
    else
    printf("Not so big... :(");


    ...into this:

    if(a > 10)
    
    printf("It's so big!");
    else if(a < 10)
    printf("Not so big... :(");


    What happens if a is 10?

    Yes, I understand how the terrible reverse-ifs resulted in "no fewer than ten bugs [being] created in the process".

    But that doesn't help me understand "creating code paths that did not assign these variables".


    An example in c++ would be:

    float x;

    if (x > 10) {

    }

    Defining x without initialising it to something (eg = 5.4f) means that it'll just contain the value of whatever was as that memory location. Could be any number, and results can change every time you run it.
  • Meta-commentator 2012-11-14 09:25
    Seeing a marginal WTF, expects great reams of meta commentary on the post about the failure. Meta commentary does not exisist.

    So fail
  • Ben Jammin 2012-11-14 09:27
    Max:
    LoremIpsumDolorSitAmet:
    ...
    Yes, I understand how the terrible reverse-ifs resulted in "no fewer than ten bugs [being] created in the process".

    But that doesn't help me understand "creating code paths that did not assign these variables".


    An example in c++ would be:

    float x;

    if (x > 10) {

    }

    Defining x without initialising it to something (eg = 5.4f) means that it'll just contain the value of whatever was as that memory location. Could be any number, and results can change every time you run it.

    Your example breaks an if/else as well as an if/else if. Refer to Kaso's.
  • jonkenson 2012-11-14 09:28
    I took that to mean that using this if - else if style would complicate things further up.

    "Doug was a go-getter. He made the effort to go through the rest of the module and bring all the if/else statements into his if/else if "pattern"."

    So essentially using this style, he introduced bugs higher up in the code that trickled down to cause a RWTF issue in this code.
  • Geoff 2012-11-14 09:28
    Because if you convert if .. else, into if .. else if !(cond) and you screw up the !(cond) part suddenly you have code where neither the if clause nor the else clause gets executed where it would have alsways been the case at least one would have been run before.
  • Buffoon 2012-11-14 09:28
    LoremIpsumDolorSitAmet:
    Anonymous Cow:
    LoremIpsumDolorSitAmet:
    I don't understand this. Where are these new code paths? Is he talking about the possibility of some variable being undefined and therefore the IF and the ELSE IF both eval to false and neither block is executed?

    The issue that they're referring to would come up if they changed this:

    if(a > 10)
    
    printf("It's so big!");
    else
    printf("Not so big... :(");


    ...into this:

    if(a > 10)
    
    printf("It's so big!");
    else if(a < 10)
    printf("Not so big... :(");


    What happens if a is 10?

    Yes, I understand how the terrible reverse-ifs resulted in "no fewer than ten bugs [being] created in the process".

    But that doesn't help me understand "creating code paths that did not assign these variables".



    int bar = 10;
    int foo;

    if(10 > bar)
    foo = 10;
    else if(10 < bar)
    variable = -10;


    Something like that spells it out enough for you?
  • Buffoon 2012-11-14 09:29
    Buffoon:
    LoremIpsumDolorSitAmet:
    Anonymous Cow:
    LoremIpsumDolorSitAmet:
    I don't understand this. Where are these new code paths? Is he talking about the possibility of some variable being undefined and therefore the IF and the ELSE IF both eval to false and neither block is executed?

    The issue that they're referring to would come up if they changed this:

    if(a > 10)
    
    printf("It's so big!");
    else
    printf("Not so big... :(");


    ...into this:

    if(a > 10)
    
    printf("It's so big!");
    else if(a < 10)
    printf("Not so big... :(");


    What happens if a is 10?

    Yes, I understand how the terrible reverse-ifs resulted in "no fewer than ten bugs [being] created in the process".

    But that doesn't help me understand "creating code paths that did not assign these variables".



    int bar = 10;
    int foo;

    if(10 > bar)
    foo = 10;
    else if(10 < bar)
    foo = -10;


    Something like that spells it out enough for you?


    Fix...
  • Fred 2012-11-14 09:33
    Elseif can be useful. But it can ended in a mess
  • Abico 2012-11-14 09:40
    LoremIpsumDolorSitAmet:
    Justsomedudette:
    LoremIpsumDolorSitAmet:

    If so, TRWTF is using a loosely typed run-time language like JavaScript or PHP that allow undefined variables... especially in life-critical apps.

    Or, more likely, I've been mislead by Alex's brillant editing.
    That would be Mark's brilliant editing, but please don't let accuracy or spelling ruin a perfectly snide comment.

    Just because Mark submitted it doesn't mean it didn't get preprocessed by the almighty Alex! Or maybe Mark is his sockpuppet. Or maybe they're just as brillant as each other.

    PS. 'brillant' is not a typo; you must be new here!

    You've been misled into thinking that was the referenced typo.
  • Rob Z 2012-11-14 09:43
    Works fine in Oracle pl/sql:

    DECLARE
    a BOOLEAN;
    BEGIN
    IF ( a )
    THEN
    DBMS_OUTPUT.PUT_LINE( 'true' );
    ELSIF ( not a )
    THEN
    DBMS_OUTPUT.PUT_LINE( 'false' );
    ELSE
    DBMS_OUTPUT.PUT_LINE( 'null=> other universe?' );
    END IF;
    END;

    Output: 'null=> other universe?'
  • TheRider 2012-11-14 09:45
    Ben Jammin:
    Mike:
    shouldn't it be
    ...
    else if !patient.sick? || patient.dead?
    ...

    Plus, if you're not sick, hopefully being buried isn't the solution. Obviously, patient.sick? needs to be a tri-state boolean of true, false, and LIFE_NOT_FOUND.
    Don't you make me spit my coffee on the screen. Too much work cleaning it...
  • u 2012-11-14 09:53
    Is doing nothing when a== 0, b >= 30 and c != null intentional? If not it somehow proves the point...
  • Cbuttius 2012-11-14 09:56
    the correct construct is of course to first create a boolean of the condition.

    bool val = (a > 10 || b < 30 || c = null );
    if( val == true )
    {
    do_soemthing();
    }
    else if ( val == false )
    {
    do_something_else();
    }
    else if ( val == fileNotFound )
    {
    do_anything_you_like();
    }

  • foo 2012-11-14 10:02
    Reminds me of another "experienced" developer, who'd always use the mouse to select items and then do copy&paste through the context menu. Another one of those valued developers with over a decade of experience ...
  • Nemo 2012-11-14 10:04
    Ben Jammin:
    Mike:
    shouldn't it be
    ...
    else if !patient.sick? || patient.dead?
    ...

    Plus, if you're not sick, hopefully being buried isn't the solution. Obviously, patient.sick? needs to be a tri-state boolean of true, false, and LIFE_JIM_BUT_NOT_AS_WE_KNOW_IT.


    FTFY
  • foo 2012-11-14 10:09
    Doug adamantly refused to make the changes that Matt asked, and Matt refused to sign off to allow his development to advance.
    That was when Doug threatened Matt: "Now do sign off my changes OR ELSE ... do not sign off my changes!"
  • allo 2012-11-14 10:14
    if(i++ == 1){
    doSomething();
    }else if(i++ == 1){
    doSomethingElse();
    }
  • Anoldhacker 2012-11-14 10:15
    It's probably late for this, but...

    The real problem with

    if (condition)
    {...}
    elsif (reverse_of_condition)
    {...}
    end

    Is not that YOU might mess up your reverse_of_condition computation. We can assume that YOU are smart enough to use !(condition) for that. The real problem is that at some point condition will need to be modified. By someone who has never seen this code before. Who isn't as smart as you.

    That's what "doubled the complexity" meant.

  • operagost 2012-11-14 10:26
    Michael P:
    Some coding standards (like, say, the ones used for C++ on the US Joint Strike Fighter program) specifically require an if/else if chain to be terminated with either an "else" handler or a comment that explains why there is no else. That seems like good practice for any software with significant safety implications.

    Just in case of FILE_NOT_FOUND in your boolean.
  • chris 2012-11-14 10:31
    Rob Z:
    Works fine in Oracle pl/sql:

    DECLARE
    a BOOLEAN;
    BEGIN
    IF ( a )
    THEN
    DBMS_OUTPUT.PUT_LINE( 'true' );
    ELSIF ( not a )
    THEN
    DBMS_OUTPUT.PUT_LINE( 'false' );
    ELSE
    DBMS_OUTPUT.PUT_LINE( 'null=> other universe?' );
    END IF;
    END;

    Output: 'null=> other universe?'


    IIRC it's the ANSI standard: null != null. Its the same in T-SQL (SQL Server) by default. One hell of an annoying convention.
  • TRWTFVB 2012-11-14 10:39
    TRWTF is that he had decades of experience in VB
  • iusto 2012-11-14 10:55
    foo:
    Reminds me of another "experienced" developer, who'd always use the mouse to select items and then do copy&paste through the context menu. Another one of those valued developers with over a decade of experience ...


    Now you're exaggerating a little. If you had said, a guy scrolls up 2 pages of text to copy a short word so that he can paste it where he was below (to avoid typing it), then I'd understand. I noticed a couple of devs doing that for as little as 4-characters. Not to mention that IDE at the time was Visual Studio, where intellisense is present.
  • DB 2012-11-14 11:04
    Ben Jammin:
    Mike:
    shouldn't it be
    ...
    else if !patient.sick? || patient.dead?
    ...

    Plus, if you're not sick, hopefully being buried isn't the solution. Obviously, patient.sick? needs to be a tri-state boolean of true, false, and LIFE_NOT_FOUND.


    HAHAHAAHAHHAA
  • Paul Neumann 2012-11-14 11:13
    iusto:
    foo:
    Reminds me of another "experienced" developer, who'd always use the mouse to select items and then do copy&paste through the context menu. Another one of those valued developers with over a decade of experience ...
    Now you're exaggerating a little. If you had said, a guy scrolls up 2 pages of text to copy a short word so that he can paste it where he was below (to avoid typing it), then I'd understand. I noticed a couple of devs doing that for as little as 4-characters. Not to mention that IDE at the time was Visual Studio, where intellisense is present.
    Real developers have no mouse. Real developers have no keyboard. Real developers whistle at 900 baud to a modem attached to ttyS0!
  • Mythran 2012-11-14 11:22
    Optimizing your code, with a few bug fixes:

    // No matter what, bury the patient first...
    if ((patient.sick || !patient.sick) && (patient.dead || !patient.dead))
    buryPatient();
    } else if ((!patient.sick && patient.sick) || (!patient.dead && patient.dead)) {
    // If we get here, the patient is God, lets heal him!
    healPatient();
    }

    // It's ZOMBIE time!
    doCreateZombieFromPatient();
  • Mythran 2012-11-14 11:25
    William F:
    CAPTCHA: ague - what I get from some of these stories


    How do you pronounce "ague"? "A jew" or "ag you" or "a goo" or "a gua" or ? Different pictures pop into my head depending on how it's pronounced :P
  • Stabbitha 2012-11-14 11:28
    Where's the damn ponies?
  • Todd Lewis 2012-11-14 11:34
    What I don't understand is, how can anybody who knows enough about programming to even make this mistake correctly not understand the problem with this type of logic? In all seriousness, WTF was he thinking, and why was he continuing to think it?
  • Melnorme 2012-11-14 11:55
    blah
  • cellocgw 2012-11-14 11:59
    Mythran:
    William F:
    CAPTCHA: ague - what I get from some of these stories


    How do you pronounce "ague"? "A jew" or "ag you" or "a goo" or "a gua" or ? Different pictures pop into my head depending on how it's pronounced :P


    404 Error: Correct Pronunciation Not Found.
  • Abico 2012-11-14 12:10
    Here's how people like Doug happen:

    An engineer teaches himself to program, probably in VB. He cobbles together a project that becomes very valuable to his organization. He works in a bubble; others may glimpse the code once in a while, but they're too busy with their own work to improve on the code. They may make recommendations, but Doug scoffs at the elitist attitude of "professional" programmers.

    "Why size arrays correctly when modern machines have practically infinite memory? Just make it as big as possible!"

    "Source versioning? Every change I make improves the code, so why keep the old versions? Besides, I know what changes I've made."

    "I'm getting nanosecond response time. See, these floats tell me so."

    "VB6 isn't multithreaded? Ha! It is in my code."

    Anyway, years of honing one piece of code and inertia imbue Doug with a false sense of understanding and confidence. He really thinks he knows what he's doing; in fact he thinks he knows better than everyone else. Hence, Doug.

    Yes, I could submit a week's worth of TDWTFs about the Doug I knew.
  • dkallen 2012-11-14 12:15
    Abico:


    <snip>

    Yes, I could submit a week's worth of TDWTFs about the Doug I knew.


    It's not the Doug you know that gets you.
    It's the Doug you *don't* know.
  • plaidfluff 2012-11-14 12:18
    chris:
    Rob Z:
    Works fine in Oracle pl/sql:

    DECLARE
    a BOOLEAN;
    BEGIN
    IF ( a )
    THEN
    DBMS_OUTPUT.PUT_LINE( 'true' );
    ELSIF ( not a )
    THEN
    DBMS_OUTPUT.PUT_LINE( 'false' );
    ELSE
    DBMS_OUTPUT.PUT_LINE( 'null=> other universe?' );
    END IF;
    END;

    Output: 'null=> other universe?'


    IIRC it's the ANSI standard: null != null. Its the same in T-SQL (SQL Server) by default. One hell of an annoying convention.

    Yep, NULL doesn't equal anything - NULL is supposed to mean "unknown," rather than being a specific concrete value of "nothing." Unfortunately, this distinction is lost on most people (mostly because in most languages NULL means "nothing")

    You can't know if two unknown things are the same as each other, thus NULL != NULL. To check for NULL you use the 'IS NULL' test instead.
  • long johnson 2012-11-14 12:19
    that was the point indeed :)
  • If (Doug) Else If (!Doug) 2012-11-14 13:03
    dkallen:
    Abico:


    <snip>

    Yes, I could submit a week's worth of TDWTFs about the Doug I knew.


    It's not the Doug you know that gets you.
    It's the Doug you *don't* know.

    Else If (It's you the Doug && you *don't* know.)

    captcha: causa
  • Darth Paul 2012-11-14 13:03
    Anoldhacker:
    It's probably late for this, but...

    The real problem with

    if (condition)
    {...}
    elsif (reverse_of_condition)
    {...}
    end

    Is not that YOU might mess up your reverse_of_condition computation. We can assume that YOU are smart enough to use !(condition) for that. The real problem is that at some point condition will need to be modified. By someone who has never seen this code before. Who isn't as smart as you.

    That's what "doubled the complexity" meant.



    More obviously, defining a fact (or piece of logic) in more than one location ensures things will go wrong down the track.
  • Michael 2012-11-14 13:05
    Luckily for Matt and the customers, management stepped in to end the stalemate. Doug is now the newest ex-developer...

    Now I know this is a fake story. Anyplace I've ever worked they would've fired Matt for being so "unreasonable".
  • Jack 27 2012-11-14 13:18
    Anoldhacker:
    It's probably late for this, but...

    The real problem with

    if (condition)
    {...}
    elsif (reverse_of_condition)
    {...}
    end

    Is not that YOU might mess up your reverse_of_condition computation. We can assume that YOU are smart enough to use !(condition) for that. The real problem is that at some point condition will need to be modified. By someone who has never seen this code before. Who isn't as smart as you.

    That's what "doubled the complexity" meant.



    Doug wasn't smart enough to complement the whole condition:
    else if (!(a < 10 && b >= 30 && c != null))

    He tried to complement each inequality instead, and screwed it up even before anyone came by and modified it.
  • n_slash_a 2012-11-14 13:22
    operagost:
    Michael P:
    Some coding standards (like, say, the ones used for C++ on the US Joint Strike Fighter program) specifically require an if/else if chain to be terminated with either an "else" handler or a comment that explains why there is no else. That seems like good practice for any software with significant safety implications.

    Just in case of FILE_NOT_FOUND in your boolean.

    As someone who works in the aviation industry, we do have coding standards that specify that all control paths must be covered. Thus, we have many constructs:

    if (a)
    do_something();
    else if (b)
    do_something_else();
    else
    assert(false); // should never get here

    The asserts do get compiled out in a release build, but are very good at finding things exactly like uninitialized variables.
  • n_slash_a 2012-11-14 13:24
    Abico:
    Here's how people like Doug happen:

    An engineer teaches himself to program, probably in VB. He cobbles together a project that becomes very valuable to his organization. He works in a bubble; others may glimpse the code once in a while, but they're too busy with their own work to improve on the code. They may make recommendations, but Doug scoffs at the elitist attitude of "professional" programmers.

    "Why size arrays correctly when modern machines have practically infinite memory? Just make it as big as possible!"

    "Source versioning? Every change I make improves the code, so why keep the old versions? Besides, I know what changes I've made."

    "I'm getting nanosecond response time. See, these floats tell me so."

    "VB6 isn't multithreaded? Ha! It is in my code."

    Anyway, years of honing one piece of code and inertia imbue Doug with a false sense of understanding and confidence. He really thinks he knows what he's doing; in fact he thinks he knows better than everyone else. Hence, Doug.

    Yes, I could submit a week's worth of TDWTFs about the Doug I knew.

    +1
  • foo 2012-11-14 13:25
    Abico:
    Yes, I could submit a week's worth of TDWTFs about the Doug I knew.
    Please do. :)
  • Coyne 2012-11-14 13:40
    chris:
    Rob Z:
    Works fine in Oracle pl/sql:

    DECLARE
    a BOOLEAN;
    BEGIN
    IF ( a )
    THEN
    DBMS_OUTPUT.PUT_LINE( 'true' );
    ELSIF ( not a )
    THEN
    DBMS_OUTPUT.PUT_LINE( 'false' );
    ELSE
    DBMS_OUTPUT.PUT_LINE( 'null=> other universe?' );
    END IF;
    END;

    Output: 'null=> other universe?'


    IIRC it's the ANSI standard: null != null. Its the same in T-SQL (SQL Server) by default. One hell of an annoying convention.


    If a given SQL engine correctly and fully implements NULL, then all normal predicates (= <> > <) return false if either or both test values are NULL. To test for NULL, you have to use "x IS NULL" or "ISNULL(x)" depending on the engine.

    If "a" is NULL in Rob's example then neither "if" would be true.
  • shadowman 2012-11-14 14:01
    LoremIpsumDolorSitAmet:
    by creating code paths that did not assign these variables, he would cause unpredictable behavior depending on the prior values of the variables

    I don't understand this. Where are these new code paths? Is he talking about the possibility of some variable being undefined and therefore the IF and the ELSE IF both eval to false and neither block is executed?

    If so, TRWTF is using a loosely typed run-time language like JavaScript or PHP that allow undefined variables... especially in life-critical apps.

    Or, more likely, I've been mislead by Alex's brillant editing.



    int main() {
    int x,y;
    x = 10;
    if (x>10) y = 1;
    else if (x<10) y = 2;
    printf("%d", y);
    }
  • Herp 2012-11-14 15:12
    Forgive me if this has already been mentioned, but if the intention is to have an else if contain an inverse condition to the if (that is, catch anything that the if does not catch), and the else if does not execute due to a logical error, then an important branch of code may be unexpectedly missed (by the developer) due to someone's stubborn refusal to use an else.
  • urbalt 2012-11-14 15:24
    Abico:
    Here's how people like Doug happen:

    An engineer teaches himself to program, probably in VB. He cobbles together a project that becomes very valuable to his organization. He works in a bubble; others may glimpse the code once in a while, but they're too busy with their own work to improve on the code. They may make recommendations, but Doug scoffs at the elitist attitude of "professional" programmers.

    "Why size arrays correctly when modern machines have practically infinite memory? Just make it as big as possible!"

    "Source versioning? Every change I make improves the code, so why keep the old versions? Besides, I know what changes I've made."

    "I'm getting nanosecond response time. See, these floats tell me so."

    "VB6 isn't multithreaded? Ha! It is in my code."

    Anyway, years of honing one piece of code and inertia imbue Doug with a false sense of understanding and confidence. He really thinks he knows what he's doing; in fact he thinks he knows better than everyone else. Hence, Doug.

    Yes, I could submit a week's worth of TDWTFs about the Doug I knew.


    A wise person once described this idea to me as: "some people with twenty years of experience really have twenty years of experience; some people with twenty years of experience just have one year of experience, twenty times."
  • herby 2012-11-14 15:29
    Herwig:

    if (a)
    {
    doSomething();
    }
    else if (!a)
    {
    doSomethingElse();
    }
    else
    {
    file_not_found();
    }


    FTFY
  • Jack 2012-11-14 15:54
    Darth Paul:
    defining a fact (or piece of logic) in more than one location ensures things will go wrong down the track.
    Right. That's why you need an "if statement wrapper":
    Function IFF (condition) {
    
    if (condition) {
    return true;
    } else if (!condition) {
    return false;
    } else if (true) {
    throw new universeException;
    } else if (!true) {
    throw new compilerBugFoundException;
    } else {
    assert ("Should'nt happen");
    }
    }
  • Abico 2012-11-14 16:10
    urbalt:
    Abico:
    Here's how people like Doug happen:

    An engineer teaches himself to program, probably in VB. He cobbles together a project that becomes very valuable to his organization. He works in a bubble; others may glimpse the code once in a while, but they're too busy with their own work to improve on the code. They may make recommendations, but Doug scoffs at the elitist attitude of "professional" programmers.

    "Why size arrays correctly when modern machines have practically infinite memory? Just make it as big as possible!"

    "Source versioning? Every change I make improves the code, so why keep the old versions? Besides, I know what changes I've made."

    "I'm getting nanosecond response time. See, these floats tell me so."

    "VB6 isn't multithreaded? Ha! It is in my code."

    Anyway, years of honing one piece of code and inertia imbue Doug with a false sense of understanding and confidence. He really thinks he knows what he's doing; in fact he thinks he knows better than everyone else. Hence, Doug.

    Yes, I could submit a week's worth of TDWTFs about the Doug I knew.


    A wise person once described this idea to me as: "some people with twenty years of experience really have twenty years of experience; some people with twenty years of experience just have one year of experience, twenty times."

    I love it.
  • tation 2012-11-14 16:23
    Todd Lewis:
    What I don't understand is, how can anybody who knows enough about programming to even make this mistake correctly not understand the problem with this type of logic? In all seriousness, WTF was he thinking, and why was he continuing to think it?


    Simply put: he's a dumbass - who managed somehow to bullshit his way around jobs enough years to think of himself as someone with experience - but, in reality, he's a dumbass (and he's not the only one; no pun intended).
  • tation 2012-11-14 16:30
    n_slash_a:
    operagost:
    Michael P:
    Some coding standards (like, say, the ones used for C++ on the US Joint Strike Fighter program) specifically require an if/else if chain to be terminated with either an "else" handler or a comment that explains why there is no else. That seems like good practice for any software with significant safety implications.

    Just in case of FILE_NOT_FOUND in your boolean.

    As someone who works in the aviation industry, we do have coding standards that specify that all control paths must be covered. Thus, we have many constructs:

    if (a)
    do_something();
    else if (b)
    do_something_else();
    else
    assert(false); // should never get here

    The asserts do get compiled out in a release build, but are very good at finding things exactly like uninitialized variables.



    That logic is dumb, as is who imposed it on you, as are you who accepts it. Reading that tears my head. If my employer made my type that, I would quit. I my employee typed that, I would fire them. I don't care if you're coding a blog or software to control jets - it's dumb, and it doesn't make sense.
  • Nagesh 2012-11-14 16:59
    Paul Neumann:
    Real developers have no mouse. Real developers have no keyboard. Real developers whistle at 900 baud to a modem attached to ttyS0!

    Flood of obligatory xkcd links to follow in 3 ... 2 ... 1 ...
  • Gunslinger 2012-11-14 17:25
    So, TRWTF is that the correct thing happened and it's still being shown on this website?
  • Gunslinger 2012-11-14 17:40
    tation:
    n_slash_a:
    operagost:
    Michael P:
    Some coding standards (like, say, the ones used for C++ on the US Joint Strike Fighter program) specifically require an if/else if chain to be terminated with either an "else" handler or a comment that explains why there is no else. That seems like good practice for any software with significant safety implications.

    Just in case of FILE_NOT_FOUND in your boolean.

    As someone who works in the aviation industry, we do have coding standards that specify that all control paths must be covered. Thus, we have many constructs:

    if (a)
    do_something();
    else if (b)
    do_something_else();
    else
    assert(false); // should never get here

    The asserts do get compiled out in a release build, but are very good at finding things exactly like uninitialized variables.


    That logic is dumb, as is who imposed it on you, as are you who accepts it. Reading that tears my head. If my employer made my type that, I would quit. I my employee typed that, I would fire them. I don't care if you're coding a blog or software to control jets - it's dumb, and it doesn't make sense.


    No, you're dumb, for not specifying what part doesn't make sense. There are several concepts in the post you quoted and several of them do make sense and are not dumb. For instance, the main concept is that all control paths must be covered, which is not a dumb thing to require. So, because we can assume that you're calling that dumb logic, we must assume that you are the dumb one. QED
  • Ben Jammin 2012-11-14 17:57
    tation:
    n_slash_a:
    <snip>
    As someone who works in the aviation industry, we do have coding standards that specify that all control paths must be covered. Thus, we have many constructs:

    if (a)
    do_something();
    else if (b)
    do_something_else();
    else
    assert(false); // should never get here

    The asserts do get compiled out in a release build, but are very good at finding things exactly like uninitialized variables.



    That logic is dumb, as is who imposed it on you, as are you who accepts it. Reading that tears my head. If my employer made my type that, I would quit. I my employee typed that, I would fire them. I don't care if you're coding a blog or software to control jets - it's dumb, and it doesn't make sense.


    // test flying object (fo) type...
    if(fo.hasBeak)
    return "It's a bird!"
    else if (fo.hasWings)
    return "It's a plane!"
    else
    assert(false) // Superman ain't real!
  • Simon 2012-11-14 18:06
    chris:
    IIRC it's the ANSI standard: null != null. Its the same in T-SQL (SQL Server) by default. One hell of an annoying convention.


    Yes, that's standard SQL. And yes, *very* poorly thought out... resulting in expressions like (x = y or (x is null and y is null)) scattered throughout the system... and as often than not, someone has the conditions wrong.
  • Simon 2012-11-14 18:13
    tation:
    That logic is dumb, as is who imposed it on you, as are you who accepts it. Reading that tears my head. If my employer made my type that, I would quit. I my employee typed that, I would fire them. I don't care if you're coding a blog or software to control jets - it's dumb, and it doesn't make sense.


    It's not dumb - it's just paranoid. And sometimes, that kind of paranoia is a really good idea - if something should never happen, don't just assume that it never will.
  • JV 2012-11-14 18:36
    TRWTF is that he got hired in the first place.
  • Buzz Lightning 2012-11-14 18:57
    FRIST!!! I did it - FINALLY!
  • some pony 2012-11-14 18:58
    n_slash_a:

    As someone who works in the aviation industry, we do have coding standards that specify that all control paths must be covered. Thus, we have many constructs:

    if (a)
    do_something();
    else if (b)
    do_something_else();
    else
    assert(false); // should never get here

    The asserts do get compiled out in a release build, but are very good at finding things exactly like uninitialized variables.


    For cases including 'c' 'd' 'e' and 'f', i would agree, but when one has just two statements, would it not be more prudent to do assert(b) in the else clause together with do_something_else(); rather then to create the third clause to assert false?
  • Jimbo 2012-11-14 19:01
    LoremIpsumDolorSitAmet:
    by creating code paths that did not assign these variables, he would cause unpredictable behavior depending on the prior values of the variables

    I don't understand this. Where are these new code paths? Is he talking about the possibility of some variable being undefined and therefore the IF and the ELSE IF both eval to false and neither block is executed?

    If so, TRWTF is using a loosely typed run-time language like JavaScript or PHP that allow undefined variables... especially in life-critical apps.

    Or, more likely, I've been mislead by Alex's brillant editing.
    I don't think Alex has been making these up for some time now....he's got a group of brainstormers to [strikethrough]create[/strikethrough] collaborate the stories now!!
  • Gigaplex 2012-11-14 19:27
    I disagree to some extent. NULL to me means "known to be invalid", not "unknown". Something logically can be valid but unknown given the context. If two things are known to be invalid they can logically be considered equivalent.
  • Mikhail 2012-11-14 19:40
    Geoff:
    Because if you convert if .. else, into if .. else if !(cond) and you screw up the !(cond) part suddenly you have code where neither the if clause nor the else clause gets executed where it would have alsways been the case at least one would have been run before.


    static int mushroomsPicked = 4;
    int getMushrooms()
    {
    return mushroomsPicked++;
    }


    main()
    {
    if(getMushrooms()<5)
    {
    printf("We need to pick more mushrooms\n");
    }
    if(getMushrooms() == 5)
    {
    printf("We can stop now\n");
    }
    else if(getMushrooms()>5)
    {
    printf("How the hell did we pick too many mushrooms?\n");
    }
    }

  • Mikhail 2012-11-14 19:41
    Mikhail:
    Geoff:
    Because if you convert if .. else, into if .. else if !(cond) and you screw up the !(cond) part suddenly you have code where neither the if clause nor the else clause gets executed where it would have alsways been the case at least one would have been run before.


    static int mushroomsPicked = 4;
    int getMushrooms()
    {
    return mushroomsPicked++;
    }


    main()
    {
    if(getMushrooms()<5)
    {
    printf("We need to pick more mushrooms\n");
    }
    else if(getMushrooms() == 5)
    {
    printf("We can stop now\n");
    }
    else if(getMushrooms()>5)
    {
    printf("How the hell did we pick too many mushrooms?\n");
    }
    }


    FTFM
  • willie 2012-11-14 19:44
    Nemo:
    Ben Jammin:
    Mike:
    shouldn't it be
    ...
    else if !patient.sick? || patient.dead?
    ...

    Plus, if you're not sick, hopefully being buried isn't the solution. Obviously, patient.sick? needs to be a tri-state boolean of true, false, and SCHRODINGERS_CAT.


    FTFY

    FTFAOY



    All of
  • flutes 2012-11-14 19:52
    plaidfluff:
    chris:
    Rob Z:
    Works fine in Oracle pl/sql:

    DECLARE
    a BOOLEAN;
    BEGIN
    IF ( a )
    THEN
    DBMS_OUTPUT.PUT_LINE( 'true' );
    ELSIF ( not a )
    THEN
    DBMS_OUTPUT.PUT_LINE( 'false' );
    ELSE
    DBMS_OUTPUT.PUT_LINE( 'null=> other universe?' );
    END IF;
    END;

    Output: 'null=> other universe?'


    IIRC it's the ANSI standard: null != null. Its the same in T-SQL (SQL Server) by default. One hell of an annoying convention.

    Yep, NULL doesn't equal anything - NULL is supposed to mean "unknown," rather than being a specific concrete value of "nothing." Unfortunately, this distinction is lost on most people (mostly because in most languages NULL means "nothing")

    You can't know if two unknown things are the same as each other, thus NULL != NULL. To check for NULL you use the 'IS NULL' test instead.

    Does infinity = infinity?

    It's kind of the same concept. NULL is nothing - it's not specific (it's not really quantifiable - it's not even 0 - having none of something is not the same as having nothing (none of everythiong))). You can't compare two nothings and decide they're the same, bnecause they're, well nothing.
    Infinity is massviely big and not specific.

    I'm goin for a panadlol
  • newfweiler 2012-11-14 19:55
    if (++a == 0) {
    a = a + 1;
    } else if (++a != 0) {
    a = a + 2;
    }
  • MarkJ 2012-11-14 19:56
    Jimbo:
    LoremIpsumDolorSitAmet:
    by creating code paths that did not assign these variables, he would cause unpredictable behavior depending on the prior values of the variables

    I don't understand this. Where are these new code paths? Is he talking about the possibility of some variable being undefined and therefore the IF and the ELSE IF both eval to false and neither block is executed?

    If so, TRWTF is using a loosely typed run-time language like JavaScript or PHP that allow undefined variables... especially in life-critical apps.

    Or, more likely, I've been mislead by Alex's brillant editing.
    I don't think Alex has been making these up for some time now....he's got a group of brainstormers to [strikethrough]create[/strikethrough] collaborate the stories now!!
    The extra code paths come from the extra logic required to test for the !(condition), assuming that the "!(condition)" is actually coded correctly. Doug just doesn't understand how programming languages work; the "else" branch will always be taken if the "if" branch fails. The only time that "anything can happen" is if the processor is broken.

    I'll just go back under my bridge now.
  • havokk 2012-11-14 20:32
    Gigaplex:
    I disagree to some extent. NULL to me means "known to be invalid", not "unknown".

    Then you need to re-read Codd's 12 Rules. In a RDBMS, null markers indicate missing or inapplicable data.
    Example of missing data: Birthdate of someone whose birth records were lost. They do have a birthday but they don't know which day of the year it was.
    Example of inapplicable: Weight of a mp3 file. Hair colour of a bald man.
    Thought experiment: Stick your right hand into a bowl of lollies, grab a handful, and then remove your closed fist from the bowl. How many lollies are in your right hand? Unknown. There is an actual value - you just don't know it at this point in time (without opening your fist and couting the lollies).
    Now put three lollies in your left hand. Is the number of lollies in your left hand equal to the number of lollies in your right hand? Well, since the number of lollies in your right hand is unknown then you can't know if they are equal or not.
    KnownValue = NULL --> NULL.
    Next thought experiment: Stick both hands into the bowl and grab a handful of lollies. Is the number of lollies in your left hand equal to the number of lollies in your right hand? Since you don't know the number of lollies in either hand then you can't know if they are equal or not.
    NULL = NULL --> NULL.
    Hint: Use the phrase "null marker" rather than "null value". It will help reduce misunderstandings. For "missing", use words like "maybe", "perhaps", "possibly", "dunno".
    P.S. null markers in a RDBMS have nothing to do with null pointers in programming languages.
  • Zylon 2012-11-14 20:41
    Simon:
    It's not dumb - it's just paranoid. And sometimes, that kind of paranoia is a really good idea - if something should never happen, don't just assume that it never will.

    What's dumb is feeding the trolls. Knock it off.
  • Eric Jablow 2012-11-14 20:58
    And then there's:


    private volatile boolean b;

    //Method that updates b.

    //Other method that updates b

    public void failsRandomly() {
    if (b) {
    bWasTrue();
    else if (!b) {
    bWasFalse();
    } else {
    bWasFileNotFound();
    }
    }
  • Norman Diamond 2012-11-14 21:12
    Michael P:
    Some coding standards (like, say, the ones used for C++ on the US Joint Strike Fighter program)
    But not the ones used for civil aviation? No wonder knowledgeable people were afraid to fly even before the TSA made it worse.

    Michael P:
    specifically require an if/else if chain to be terminated with either an "else" handler or a comment that explains why there is no else. That seems like good practice for any software with significant safety implications.
    operagost:
    Just in case of FILE_NOT_FOUND in your boolean.
    Only if the preceding code was "if (something) doit else if (!something) dontit" instead of a plain "if (something) doit else dontit". If it was a nullable boolean then the former version needs "else circularfileit".

    n_slash_a:
    As someone who works in the aviation industry, we do have coding standards that specify that all control paths must be covered. Thus, we have many constructs:

    if (a)
    do_something();
    else if (b)
    do_something_else();
    else
    assert(false); // should never get here

    The asserts do get compiled out in a release build, but are very good at finding things exactly like uninitialized variables.
    TRWTF. By compiling out the error checking, you arrange for errors to result in crashes instead of bug reports. Just like giving black boxes to test pilots but omitting black boxes from planes in actual use by the public.

    I'd rather see the plane tell the pilot "Keep your eyes open and talk to traffic control now because I'm going to spend the next 5 minutes rebooting" instead of "resume next and crash".
  • Norman Diamond 2012-11-14 21:26
    Mike:
    shouldn't it be
    ...
    else if !patient.sick? || patient.dead?
    ...
    If a plane crashes on the border between the United States and Canada, where will the survivors be buried?
  • Norman Diamond 2012-11-14 21:33
    foo:
    Reminds me of another "experienced" developer, who'd always use the mouse to select items and then do copy&paste through the context menu. Another one of those valued developers with over a decade of experience ...
    Oh neat, a story about a developer who adds bugs by doing unnecessary editing reminds you of another developer who sometimes avoided adding bugs by double checking the editing they were about to do?

    If the programmer remembers they want to use the same variable that was used two screenfuls of code earlier, but doesn't remember what it was called, which letter should they type in order to get Intellisense to give them a list of reasonable candidates?

    Well anyway, you'd make a good manager, with typical inability to distinguish which of your subordinates are competent and which aren't. You'd discover pretty quickly which ones have no social skills, but you won't understand why, and you'll fire them immediately.
  • Scarlet Manuka 2012-11-14 21:34
    Abico:
    Here's how people like Doug happen:
    {VB6}
    {years of honing one piece of code}
    {false sense of understanding and confidence}
    {thinks he knows better than everyone else}
    Yes, I could submit a week's worth of TDWTFs about the Doug I knew.

    Let me guess, he wrote a file text searcher cum media player?
  • Scarlet Manuka 2012-11-14 21:36
    Norman Diamond:
    If a plane crashes on the border between the United States and Canada, where will the survivors be buried?

    Presumably in graveyards, eventually. Though some of them will probably be cremated rather than buried.

    Just because they didn't die in the crash doesn't make them immortal, after all.
  • PiisAWheeL 2012-11-14 22:02
    Scarlet Manuka:
    Norman Diamond:
    If a plane crashes on the border between the United States and Canada, where will the survivors be buried?

    Presumably in graveyards, eventually. Though some of them will probably be cremated rather than buried.

    Just because they didn't die in the crash doesn't make them immortal, after all.
    Depends. The survivors on the canadian side will probably go on to lead happy healthy lives. The ones on the American side will probably be sent back to their families' funeral home of choice.
  • Gigaplex 2012-11-14 22:09
    havokk:
    Gigaplex:
    I disagree to some extent. NULL to me means "known to be invalid", not "unknown".

    Then you need to re-read Codd's 12 Rules. In a RDBMS, null markers indicate missing or inapplicable data.
    Example of missing data: Birthdate of someone whose birth records were lost. They do have a birthday but they don't know which day of the year it was.
    Example of inapplicable: Weight of a mp3 file. Hair colour of a bald man.

    I've never read Codd's 12 rules, nor do I deal with databases. My perspective is from a programming point of view, and since the example in this article is about code not databases I'm going to respond from that perspective.
    havokk:

    Thought experiment: Stick your right hand into a bowl of lollies, grab a handful, and then remove your closed fist from the bowl. How many lollies are in your right hand? Unknown. There is an actual value - you just don't know it at this point in time (without opening your fist and couting the lollies).
    Now put three lollies in your left hand. Is the number of lollies in your left hand equal to the number of lollies in your right hand? Well, since the number of lollies in your right hand is unknown then you can't know if they are equal or not.
    KnownValue = NULL --> NULL.

    The number of lollies in your right hand is either a null pointer/reference or an uninitialised variable, leading to a null reference exception, compilation error, or undefined behaviour depending on programming language.
    havokk:

    Next thought experiment: Stick both hands into the bowl and grab a handful of lollies. Is the number of lollies in your left hand equal to the number of lollies in your right hand? Since you don't know the number of lollies in either hand then you can't know if they are equal or not.
    NULL = NULL --> NULL.

    Again, the variables are either null pointer/references or uninitialised variables, leading to the same issues as I mentioned above.
    havokk:

    Hint: Use the phrase "null marker" rather than "null value". It will help reduce misunderstandings. For "missing", use words like "maybe", "perhaps", "possibly", "dunno".
    P.S. null markers in a RDBMS have nothing to do with null pointers in programming languages.

    It sounds like null markers are equivalent to an amalgamation of null references and uninitialised variables.
  • Andrew 2012-11-14 22:17
    I guess that's the whole point of the negated condition check, although personally I think it is not well implemented.

    Suppose the code is written on day1 with this intention

    if (condition1) {
    doSomething();
    } else if (!condition1) {
    doSomethingElse();
    }

    It could be that the doSomethingElse() only work if !condition1, and it could be castrophic if doSomethingElse() is executed if condition1 is true.

    e.g.
    if (alive) {
    doMonitorHeartBeat();
    } else {
    injectFormalin();
    }

    Now consider a feature request to introduce a new switch to monitor heart beat, now an inexperienced developer could write code like.

    if (alive && switch == "On") { doMonitorHeartBeat(); } else { doInjectFormalin(); }

    Now he kills everyone when the switch is off!Now you see the value of insisting the else block check? Consider the doMonitorHeartBeat() is expanded into something like 300 - 400 lines - it is really easy for one to miss that.

    I feel like the right solution is Assert [Assuming you turn on assert during testing, and there are enough test cases]

    if (alive) {
    doMonitorHeartBeat();
    } else {
    Debug.Assert(!alive);
    doInjectFormalin();
    }

    or to be extra safe - to ensure the code doSomethingElse, despite a careless programmer comes in - can be executed.

    if (alive) {
    doMonitorHeartBeat();
    } else if (!alive) {
    Debug.Assert(!alive);
    doInjectFormalin();
    } else {
    Debug.Assert("Should never reach here");
    }
  • Andrew 2012-11-14 22:40
    Look - the subject of the article applies!

    Anything can happens! That "Anything" also include someone can change your code. Having robust code is nothing wrong.
  • Norman Diamond 2012-11-14 22:58
    Andrew:
    e.g.
    if (alive) {
    doMonitorHeartBeat();
    } else {
    injectFormalin();
    }

    Now consider a feature request to introduce a new switch to monitor heart beat, now an inexperienced developer could write code like.

    if (alive && switch == "On") { doMonitorHeartBeat(); } else { doInjectFormalin(); }

    Now he kills everyone when the switch is off!Now you see the value of insisting the else block check? Consider the doMonitorHeartBeat() is expanded into something like 300 - 400 lines - it is really easy for one to miss that.
    Splendid example. +infinity.

    Too bad you proceeded to fuck it up:
    Andrew:
    I feel like the right solution is Assert [Assuming you turn on assert during testing, and there are enough test cases]

    if (alive) {
    doMonitorHeartBeat();
    } else {
    Debug.Assert(!alive);
    doInjectFormalin();
    }

    or to be extra safe - to ensure the code doSomethingElse, despite a careless programmer comes in - can be executed.

    if (alive) {
    doMonitorHeartBeat();
    } else if (!alive) {
    Debug.Assert(!alive);
    doInjectFormalin();
    } else {
    Debug.Assert("Should never reach here");
    }
    You need the redundant test inside doInjectFormalin(), not here in the if statement.

    And you need the redundant test in release builds. You DON'T need this:

    } else if (!alive) {
    #if debug
    alert("fatal bug");
    abort();
    #else
    // kill(patient) in 3 ... 2 ... 1 ...
    #endif
    doInjectFormalin();
    } else {
  • Maurits 2012-11-14 23:03
    Mythran:
    William F:
    CAPTCHA: ague - what I get from some of these stories


    How do you pronounce "ague"? "A jew" or "ag you" or "a goo" or "a gua" or ? Different pictures pop into my head depending on how it's pronounced :P


    I always assumed it rhymed with "plague". But http://dictionary.reference.com/browse/ague tells me it is "ay-gyoo".
  • Wak 2012-11-15 04:07
    Hey, there are languages where Doug's pattern makes sense. For example in (System) Verilog:

    module top;
    reg x;
    initial
    if( x )
    $display(1);
    else if( !x )
    $display(2);
    else
    $display(3);
    endmodule
  • Krzysiek 2012-11-15 04:26
    Michael P:
    Some coding standards (...) specifically require an if/else if chain to be terminated with either an "else" handler or a comment that explains why there is no else. That seems like good practice for any software with significant safety implications.


    FTFY: "That seems like good practice for any software."

    BTW, MISRA also enforces that.
  • CodeWatcher 2012-11-15 04:50
    I see this had a happy ending: no patients being fried with 4 times the radiation they needed!

    It's better many times to get a developer that is green that can be trained than the 'experienced' developer.

  • renewest 2012-11-15 05:50
    if (a)
    {
    doSomething();
    }

    or else
    {
    youHaventHeardTheLastOfThis();
    }
  • vlnx 2012-11-15 05:53
    yeah, bury that poor fucker alive :-D
  • andytech 2012-11-15 07:10
    This code reminds me of a guy named Bob I used to work with - he also had an interesting conditional pattern used everywhere throughout his code:


    while(x) {
    if(x) {
    // do something
    }
    }

    with the same (sometimes not quite right) duplication of the conditional check as Doug's code. Also sometimes the conditional had side effects, which got applied twice...

    Apparently all this was necessary because "you never know - it might change between the 'while' and the 'if'"....
  • Hegel 2012-11-15 07:16
    The infamous negation operation may indeed cause interesting side-effects. Long time ago as an intern I had to bang my head against wall in a certain VB6 (*sigh*) project. A function in a certain COM component returned strange, ill-behaving "Boolean" values, which were not quite defined in a standard way.


    #define TRUE 1
    #define FALSE 0
    #define FILE_NOT_FOUND !TRUE

    fileExists=FILE_NOT_FOUND;

    if(sfileExists)
    {
    copyFile();
    }
    else if (!foo)
    {
    showError("File not found!");
    }
  • Hegel 2012-11-15 07:18
    Of course I ment to write the code as following.

    Hegel:

    #define TRUE 1
    #define FALSE 0
    #define FILE_NOT_FOUND !TRUE

    fileExists=FILE_NOT_FOUND;

    if(fileExists)
    {
    copyFile();
    }
    else if (!fileExists)
    {
    showError("File not found!");
    }
  • foo 2012-11-15 08:23
    Norman Diamond:
    If a plane crashes on the border between the United States and Canada, where will the survivors be buried?
    Gitmo (if Arab).
  • Abico 2012-11-15 08:47
    Scarlet Manuka:
    Abico:
    Here's how people like Doug happen:
    {VB6}
    {years of honing one piece of code}
    {false sense of understanding and confidence}
    {thinks he knows better than everyone else}
    Yes, I could submit a week's worth of TDWTFs about the Doug I knew.

    Let me guess, he wrote a file text searcher cum media player?

    I wish. Try dynamometer controller.
  • JimLahey 2012-11-15 08:50
    We've got a "what if something happens" person on our team. She knows literally fuck all about SQL or ORMs but can claim that "remote paging and sorting is really inefficient because you keep hitting the database. it would be much more efficient to select all the rows from the table, keep them in memory and do the paging and sorting from there".

    Despite the fact that there's this thing called "Structured Query Language", databases must only rarely be queried, because it will impact negatively on performance..

    When I asked her about concurrency in case records are added, deleted or updated she went all quiet, then countered with "opening DB connections is an expensive operation, you don't want to do that on every request". Then I asked her if she knew anything about connection pooling..

    Putting the F in WTF.
  • Alex 2012-11-15 08:57
    What about that:


    if (a)
    {
    doSomething();
    a = false;
    }
    else if (!a)
    {
    doSomethingElse();
    }


    Not that I would endorse this kind of programming, because of it being pretty unpredictable, but still. Also, C++ operator overloading could actually yield different results for (bool)(a) and (bool)(!a). Not that I would endorse that kind of programming either, but the following would actually be able to execute all three code paths, depending on operator overloading:


    if (a)
    {
    doSomething();
    }
    else if (!a)
    {
    doSomethingElse();
    }
    else
    {
    doWTF();
    }
  • Anon 2012-11-15 09:29
    Alex:

    if (a)
    {
    doSomething();
    a = false;
    }
    else if (!a)
    {
    doSomethingElse();
    }



    If a is true doSomethingElse(); would not be executed, because it doesn't check for the second if.

    This instead would execute both:

    if (a)
    {
    doSomething();
    a = false;
    }
    if (!a)
    {
    doSomethingElse();
    }
  • annonomous 2012-11-15 09:46
    Obviously he was just trying to account for the tri-state boolean.
  • AmokCrow 2012-11-15 10:05
    Let's face it. It's another victim of Visual Basic, the only language where a boolean may be something else than just true or false. It gives a whole new meaning to the "else {" structure.
  • foo2 2012-11-15 10:41
    Scarlet Manuka:

    Let me guess, he wrote a file text searcher cum media player?

    And then he went on to update Irfanview to do the same!

    Seriously Irfanview, WTF?
  • Paul Neumann 2012-11-15 11:02
    Gigaplex:
    I disagree to some extent. NULL to me means "known to be invalid", not "unknown". Something logically can be valid but unknown given the context. If two things are known to be invalid they can logically be considered equivalent.
    And when you've designed a language which is as pervasive, maybe we will care what you think about it.
  • Maurits 2012-11-15 11:17
    andytech:
    This code reminds me of a guy named Bob I used to work with - he also had an interesting conditional pattern used everywhere throughout his code:


    while(x) {
    if(x) {
    // do something
    }
    }

    with the same (sometimes not quite right) duplication of the conditional check as Doug's code. Also sometimes the conditional had side effects, which got applied twice...

    Apparently all this was necessary because "you never know - it might change between the 'while' and the 'if'"....


    I would suggest asking Bob "what happens if it changes between the 'if' and the 'do something'? Better put another 'if' in there."
  • Spider Flyer 2012-11-15 14:16
    Alex:
    What about that:


    if (a)
    {
    doSomething();
    a = false;
    }
    else if (!a)
    {
    doSomethingElse();
    }


    Not that I would endorse this kind of programming, because of it being pretty unpredictable, but still. Also, C++ operator overloading could actually yield different results for (bool)(a) and (bool)(!a). Not that I would endorse that kind of programming either, but the following would actually be able to execute all three code paths, depending on operator overloading:


    if (a)
    {
    doSomething();
    }
    else if (!a)
    {
    doSomethingElse();
    }
    else
    {
    doWTF();
    }


    Which is where the person's 'decades of experience' kicks in, he's had to deal with 'compiler idiosyncrasies' before, and wanted to guard against that.

    Image your C++ example was built into the compiler itself, and then you went and changed your Boolean logic to fit a coding standard...

    I've actually had experience with a compiler that would allow certain types of Boolean operations in an 'if' conditional and not others.

    Also, if you are getting in complex Boolean logic, then I would recommend an online Boolean simplifier to make sure that you're getting the inversion logic correct. And, to make the code easier to read, I would recommend factoring out _just_ the Boolean conditional to a separate function with an easy to understand name.
  • jay 2012-11-15 14:21
    Maurits:
    andytech:
    This code reminds me of a guy named Bob I used to work with - he also had an interesting conditional pattern used everywhere throughout his code:


    while(x) {
    if(x) {
    // do something
    }
    }

    with the same (sometimes not quite right) duplication of the conditional check as Doug's code. Also sometimes the conditional had side effects, which got applied twice...

    Apparently all this was necessary because "you never know - it might change between the 'while' and the 'if'"....


    I would suggest asking Bob "what happens if it changes between the 'if' and the 'do something'? Better put another 'if' in there."


    I can't count how many times I've seen:


    if (collection.size()>0)
    {
    for (int x = 0;x<collection.size(); ++x)
    {
    doSomething(collection.getMember(x));
    }
    }


    Or variations thereof. Like the programmer doesn't trust the test on loop counter to work in the case where the loop would execute zero times, but he apparently trusts it to work correctly in all other cases.

  • Oh, the humanity! 2012-11-15 14:24
    Wak:
    Hey, there are languages where Doug's pattern makes sense. For example in (System) Verilog:

    module top;
    reg x;
    initial
    if( x )
    $display(1);
    else if( !x )
    $display(2);
    else
    $display(3);
    endmodule


    Your example is wrong on so many levels, you know.

    I guess the point you are trying to make is:
    In a single bit variable, there could be more states than zero or one. That is true.

    Your "initial" happens at sim-time zero. Who is defining the state of 'x'? Also at sim-time zero? You got a race condition on your hand!

    Your variable 'x' is local scope to "top". Maybe there is someone accessing 'x' via 'top.x'. However "top" suggests to be the toplevel of your design/simulation (whatever you are trying to do here).

    What are you passing into $display()? Is this even valid syntax? It takes a string, no? All 8bit ASCII characters? Then your 1, 2 or 3 are non-printable values. Right?


    always @(x)
    if (x === 1'b1)
    $display("1");
    else if (x === 1'b0)
    $display("2");
    else
    $display("3");


    ... might make some more sense.

    Yes, tripple = if you compare includes 'Z's or 'X's!
    (An unitialized reg - the datatype of "x" - will be X, as in state unknown. If it is an undriven wire, you'll see a Z.)

    Or you could simply do this:

    always @(x)
    $display("x is %b at %t",x,$time);


    I am replying to a troll, ain't I?
  • jay 2012-11-15 14:28
    Gigaplex:
    havokk:
    Gigaplex:
    I disagree to some extent. NULL to me means "known to be invalid", not "unknown".

    Then you need to re-read Codd's 12 Rules. In a RDBMS, null markers indicate missing or inapplicable data.
    Example of missing data: Birthdate of someone whose birth records were lost. They do have a birthday but they don't know which day of the year it was.
    Example of inapplicable: Weight of a mp3 file. Hair colour of a bald man.

    I've never read Codd's 12 rules, nor do I deal with databases. My perspective is from a programming point of view, and since the example in this article is about code not databases I'm going to respond from that perspective.
    havokk:

    Thought experiment: Stick your right hand into a bowl of lollies, grab a handful, and then remove your closed fist from the bowl. How many lollies are in your right hand? Unknown. There is an actual value - you just don't know it at this point in time (without opening your fist and couting the lollies).
    Now put three lollies in your left hand. Is the number of lollies in your left hand equal to the number of lollies in your right hand? Well, since the number of lollies in your right hand is unknown then you can't know if they are equal or not.
    KnownValue = NULL --> NULL.

    The number of lollies in your right hand is either a null pointer/reference or an uninitialised variable, leading to a null reference exception, compilation error, or undefined behaviour depending on programming language.
    havokk:

    Next thought experiment: Stick both hands into the bowl and grab a handful of lollies. Is the number of lollies in your left hand equal to the number of lollies in your right hand? Since you don't know the number of lollies in either hand then you can't know if they are equal or not.
    NULL = NULL --> NULL.

    Again, the variables are either null pointer/references or uninitialised variables, leading to the same issues as I mentioned above.
    havokk:

    Hint: Use the phrase "null marker" rather than "null value". It will help reduce misunderstandings. For "missing", use words like "maybe", "perhaps", "possibly", "dunno".
    P.S. null markers in a RDBMS have nothing to do with null pointers in programming languages.

    It sounds like null markers are equivalent to an amalgamation of null references and uninitialised variables.


    Hmm, you seem to be confusing a C/C++ null pointer with a SQL null. In SQL, "null" is defined to mean "unknown" or "inapplicable". (Some insist that it should not be used to mean "inapplicable", but that's another story.) In C/C++, a null pointer is invalid, and exactly what that means is up to your program. You may interpret it to mean "unknown" -- I often do. Or you may interpret it to mean "invalid" or "Thursday" or whatever else you want it to mean. Or you may interpret it to mean "oops I forgot to set a value and now we're about to blow". Anyway, if you try to think of SQL nulls in terms of C null pointers, you're just going to confuse yourself. They're not the same concept.
  • jay 2012-11-15 14:42
    chris:
    IIRC it's the ANSI standard: null != null. Its the same in T-SQL (SQL Server) by default. One hell of an annoying convention.


    Just to be pedantic, in SQL "null!=null" is not a true staement. Comparisons in SQL have three possible results: true, false, and file-not-found ... I mean true, false, and null. Null in this case meaning "unknown". So "null=null" gives null, unknown. "null!=null" also gives null.

    Actually this is not entirely pedantic. Consider:


    create table t (x integer);
    insert into t(x) values (null), (42);
    select x from t where x=null;
    select x from t where x!=null;


    What is the output? Neither query returns any records.

    If it were true that null!=null, then the second query should return two records, because 42!=null and null!=null. But in fact it returns no records, because null!=null is not true, it is null.

    The technically correct statement would be that "null=null" is not true.
  • jay 2012-11-15 14:46
    The real catch to code like this is, suppose you came along months later and found:


    if (a>30 && b<10)
    {
    doSomething();
    }
    else if (a<30 && b>=10)
    {
    doSomethingElse();
    }


    Now you're left wondering: Does this code INTENTIONALLY do nothing when a==30? Or is that a mistake? If I saw such a statement in a program that did not have the pattern of negating all the IFs, I'd probably assume it was deliberate. But with all the negated IFs ... it's hard to say. You'd have to study the code and figure it out.

  • Musaran 2012-11-15 19:54
    Doug was probably told "Do not repeat yourself".

    So he repeated the opposite.

    Brilant.
  • Norman Diamond 2012-11-15 20:17
    jay:
    I can't count how many times I've seen:
    if (collection.size()>0)
    
    {
    for (int x = 0;x<collection.size(); ++x)
    {
    doSomething(collection.getMember(x));
    }
    }


    Or variations thereof. Like the programmer doesn't trust
    the test on loop counter to work in the case where the
    loop would execute zero times, but he apparently trusts it
    to work correctly in all other cases.
    That pattern is common in programs that were translated from [censored*] because in [censored*] loops did execute at least one time and programs had to have if statements ahead of the loop. As for why that pattern remains common in new programs written in languages that don't need it, that's probably just cargo cult programming. But guess what, oddly enough, it doesn't hurt anything.

    [* censored because I'm watching my language. The F at the beginning of that language doesn't stand for fuck.]
  • Wak 2012-11-16 01:51
    > Your example is wrong on so many levels, you know.
    Not really.

    > In a single bit variable, there could be more states than zero or one. That is true.
    No it is not. In a single bit variable (scalar to be exactly) there could be two states - zero and true. Bit is a 2valued type. Right? In a scalar reg variable there can be 4 states: 1'b0, 1'b1, 1'bx and 1'bz.

    > Your "initial" happens at sim-time zero. Who is defining the state of 'x'?
    IEEE Standard 1800-2009 I-6.8

    > Also at sim-time zero?
    Yes.

    > You got a race condition on your hand!
    It is hard to have a race condition with only one process.

    > Your variable 'x' is local scope to "top". Maybe there is someone accessing 'x' via 'top.x'. However "top" suggests to be the toplevel of your design/simulation (whatever you are trying to do here).
    I cannot see any other modules, console forces, pli functions etc.

    > What are you passing into $display()? Is this even valid syntax?
    Yes - IEEE Standard 1800-2009 I.21.2.

    > It takes a string, no?
    It does not have to.

    > All 8bit ASCII characters?
    No. 32-bit numbers.

    > Then your 1, 2 or 3 are non-printable values. Right?
    No.

    > I am replying to a troll, ain't I?
    No, you are not.
  • Cbuttius 2012-11-16 03:24
    In C++, a null pointer can be safely compared to a pointer for equality:

    You can assert( NULL == NULL );
    and you can assert ( NULL != p ) if p is not NULL.

    (p < NULL) and (NULL < p) are technically "undefined behaviour". They shouldn't crash / core-dump you but it's undefined whether they will return true or false (or file not found..)



  • Ale 2012-11-16 10:48
    Someone said that the complete name of Doug is "Doug DeMorgan"!
  • Matt Westwood 2012-11-16 17:38
    Mythran:
    William F:
    CAPTCHA: ague - what I get from some of these stories


    How do you pronounce "ague"? "A jew" or "ag you" or "a goo" or "a gua" or ? Different pictures pop into my head depending on how it's pronounced :P


    ay gyoo
  • Gibbon1 2012-11-16 19:23
    Abico:
    Here's how people like Doug happen:

    An engineer teaches himself to program, probably in VB.


    Um... as an engineer that often writes code, um... no. Your 'Doug' programs because he wasn't a solid engineer either. I also notice plenty of 'Dougs' from a CS background as well, inflexible, superstitious, socially inept, keepers of the cargo cult.
  • Oh, the humanity! 2012-11-17 11:19
    Wak:

    > In a single bit variable, there could be more states than zero or one. That is true.
    No it is not. In a single bit variable (scalar to be exactly) there could be two states - zero and true. Bit is a 2valued type. Right? In a scalar reg variable there can be 4 states: 1'b0, 1'b1, 1'bx and 1'bz.


    Great, lets mince words then.
    We are talking VERILOG here, right? How do you define a single bit variable? You either use 'reg' or 'wire'. And here you have (at least) the 4 states you mention. In VERILOG, is there any other way to declare a single bit variable? Apart from 'reg' or 'wire'?

    Look, in my initial statement, I am not disagreeing with you about the sentiment: "More than 2 states may exist and one might need to test for each of them." All I object to, is your choice of example. I have fallen victim of people deploying non-real-world (accademic) examples as a decoy before. That is why the "biting-reflex" engaged so readily.

    Wak:

    > Your "initial" happens at sim-time zero. Who is defining the state of 'x'?
    IEEE Standard 1800-2009 I-6.8


    Yes, the initial value of reg 'x' will be indeed 1'bx, as it has no assignment to it.

    I am a bit wary about people who are quick in citing the "STANDARD". Many of them - in my personal experience, YMMV - do not really know what they were talking about.

    I will give you the benefit of the doubt.

    Wak:

    > I am replying to a troll, ain't I?
    No, you are not.


    OK, fair enough, I apologize for calling you a troll. These days, no one knows who is real and who is faking it!

    I may be replying to a grad-student, a dedicated lecturer from a university or a veteran of many years of digital design - however the last I believe is unlikely. I do not know - the blessings of the internet.

    I have run the code you posted. (I did not even need to use any System-Verilog capable simulator to do that. Why the mention of System-Verilog in the first place? This is just plain VERILOG 101.)

    Well, I'll be damned:


    Veriwell version 2.8.7,
    Copyright (C) 1993-2008 Elliot Mednick and Mark Hummel

    Veriwell comes with ABSOLUTELY NO WARRANTY; This is free
    software, and you are welcome to redistribute it under the
    terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License,
    or (at your option) any later version.

    lxt support compiled in
    lxt2 support compiled in

    Entering Phase I...
    Compiling source file : trial0.v

    Entering Phase II...
    Entering Phase III...
    No errors in compilation
    Top-level modules:
    top

    3
    0 Errors, 0 Warnings, Compile time = 0.0, Load time = 0.0, Simulation time = 0.0

    Normal exit
    Thank you for using Veriwell


    It outputs '3' and hence took the branch wich is neither true or false. So maybe this example really tells us something?

    And OK, $display also takes an integer as argument. I did not know that. So this I learned - but I certainly won't apply that knowledge in the future. I'd like more meaningfull messages in my simulations, such as:

    $display("state 'x' detected");

    I might have done it this way:


    module top;

    reg x;

    initial
    begin

    #1;
    x = 1'b0;
    #1;
    x = 1'b1;
    #1;
    x = 1'bx;
    #1;
    x = 1'bz;

    end

    always @(x)

    if( x )

    $display("'x' is true (%b at time %t)",x,$time);

    else if( !x )

    $display("'x' is false (%b at time %t)",x,$time);

    else

    $display("'x' is undefined (%b at time %t)",x,$time);

    endmodule


    Which has a more verbose output:


    Top-level modules:
    top

    'x' is false (0 at time 1)
    'x' is true (1 at time 2)
    'x' is undefined (x at time 3)
    'x' is undefined (z at time 4)
    0 Errors, 0 Warnings, Compile time = 0.0, Load time = 0.0, Simulation time = 0.0


    But then try to explain the finer points of HDL to the audience. So maybe your post had a point after all.
  • wt 2012-11-20 17:48
    iusto:
    foo:
    Reminds me of another "experienced" developer, who'd always use the mouse to select items and then do copy&paste through the context menu. Another one of those valued developers with over a decade of experience ...


    Now you're exaggerating a little. If you had said, a guy scrolls up 2 pages of text to copy a short word so that he can paste it where he was below (to avoid typing it), then I'd understand. I noticed a couple of devs doing that for as little as 4-characters. Not to mention that IDE at the time was Visual Studio, where intellisense is present.


    Actually, I've sen that too at my own eyes, so it is no exaggeration at all. When one very senior developer has explaining some things to me (I was a newbie), he used exactly the same method (copying by mouse through menu). When I saw that, I really wanted to take the keyboard off him and do it by myself (but I didn't, obviously). Needed to say, that he grew up on mainframes, was very good on that and didn't care much about some strange windowed systems :). But I must admit, that the code he wrote was a mess - he basically wrote in C++ like if it was assembler.
  • Neil 2012-11-21 10:34
    I'm just glad that Doug hadn't heard of ?:
  • MisterFanwank 2012-11-25 03:20
    allo:
    if(i++ == 1){
    doSomething();
    }else if(i++ == 1){
    doSomethingElse();
    }


    ...

    No, dude... Just... No. That's horribly offensive.