• Fwip (unregistered) in reply to avflinsch
    avflinsch:
    They were cheaper because the typical AND gate was actually a NAND gate which fed both inputs of a second NAND gate to invert the output.

    I also recall converting circuits into all NORs also.

    NANDs are actually cheaper in hardware than NORs, even though they use the same number of transistors, assuming you want a gate with balanced rise/fall times (you usually do).

    PMOS transistors are about 2x-3x as large as NMOS transistors, and a NAND allows you to use two double-width NMOS and two normal-width PMOS, whereas a NOR requires the PMOS to be double width and the NMOS normal.

    I didn't explain this very well, but I swear it's at least mostly true.

  • tB (unregistered) in reply to Ed
    Ed:
    FriedDan:
    As for the WTF in the WTF, I'm not even sure why the else-if statement is relevant without a switch.

    It could be written:

    if(mainType == 7)
        subType = 4;
    if(mainType == 9)
        subType = 6;
    if(mainType == 11)
        subType = 9;
    

    There's no potential overlap so no NEED for an else (even if it might make it more readable).

    But what if mainType is 7, 9 AND 11? Then you're just screwed!

    CAPTCH: dignissim (missingID backwards, perhaps?)

    I am amazed nobody has been able to solve this problem correctly thus far...

    if(mainType == 7) { subType = 4; goto subtypingDone; } if(mainType == 9) { subType = 6; goto subtypingDone; } if(mainType == 11) { subType = 9; goto subtypingDone; } subtypingDone: /* Some more code */

  • hdgdl (unregistered)

    Meh, I'ma have to start adding some

    while(true){ ... break; }

    into my code, just to screw with people ^^

  • Jichael Mackson (unregistered) in reply to muzzylogic
    muzzylogic:
    What's wrong with a swtich/case construct?
    It doesn't exist.
  • (cs) in reply to apaq11
    apaq11:
    It's been a while since my Computer Engineering classes but from what I remember the reason for using NAND gates instead of OR/AND gates was because they had less transistors making them cheaper. This also meant their propagation delay was lower and thus faster than an equivalent AND/OR circuit.

    I vaguely recall exercises in converting AND/OR circuits into only NAND gates.

    If NAND gates are cheaper and/or faster, but if you havce to use more of them to implement the other curcuits, isn't it a tradeoff? And the AND or OR gates might be cheaper overall than using NAND gates with other hardware?

  • (cs)

    Everyone and their mother knows that else if and even switch are way less efficient than a while loop with ifs and breaks. Come on guys, RTFM.

  • gus (unregistered)

    Go lookup the history of the "NORDIC" computer.

    An early computer, made up of just NOR gates.

  • czech (unregistered) in reply to halcyon1234
    halcyon1234:
    Else if and switch sound good, but what are you going to do when mainType == 7 AND mainType == 9, huh?
    Well, you can just assign a tuple to the "subType":
    subType = (4, 6) # notice I can suddenly leave out ";"
    And it will even automagically work with the rest of the code without any further modifications!
  • BruceJ (unregistered)

    You know, that looks a lot like the Perl code to emulate a 'CASE' statement, in fact it looks almist identical to the sample code in the Camel. The "switch" builtin is planned for Perl 6.

    It also looks very vaguly like the old Applesoft Basic way to do a case statement...

  • (cs) in reply to the beholder
    the beholder:
    No, he's just using Schrodinger's integers.

    Schrodinger's integers collapse to a fixed state during the test in the first "if" and so this logic would work fine for them.

    I think you meant "Heisenberg's integers", which change to a new value every time you test them.

  • Mac (unregistered)

    This is clearly an attempt to make a simple task look more complex (by slightly longer, further indented code).

    Any manager would instantly recognise that this was no trivial task and that the contractor was worth the 6 months he charged to nut out so difficult a problem....

  • Andrei (unregistered)

    I don't want to be mean, but aren't most logic gates actually implemented using NAND gates? I think they're actually the cheapest option for implementing most binary logic, at least that's how it was with TTL technology.

  • Gerrit (unregistered) in reply to frits
    frits:
    If mainType is 7, 9 AND 11 your screwed anyway because you either have major thread sync issues, or you have landed in an alternate universe.

    I think you'll find that landing in an alternate universe actually is a major thread sync issue.

  • ioccc (unregistered)

    Wait! Maybe, because this is C++, the variable mainType is an object which has the comparison operator overloaded, i.e. operator==(int), with side effects. So when you compare the mainType == 7 it actually modifies the mainType to 9. Thus the second comparison is executed.

    Additionally, the assignment operator for the object which subType is an instance of has been overloaded as well.

    Bottom line, this could be the most devious piece of code we have ever seen! It isn't a WTF; it is a backdoor into the application! The contractor is actually a world class hacker out to undermine your company for not renewing his contract!

    {lmfao}

  • Laughing Jack (unregistered) in reply to frits
    frits:
    Any procedural solution for what this code is attempting would be smelly. However, I must say this is probably one of the ugliest ways to do it.
    So, how would you impliment what should be a simple switch statement? Recursively? Or perhaps you'd write a class just to encapsulate this switch?

    Congratulations, you're TRWTF.

  • NOOBS! (unregistered)

    HA! only a coward would use a switch/if else on a volatile variable ^^

  • ClaudeSuck.de (unregistered) in reply to Wade
    Wade:
    I have to deal with a lot of this kind of thing:

    subType = (mainType == 7 || mainType == 9) ? (mainType - 3) : (mainType == 11) ? (mainType - 2) : mainType;

    Why not use mainType right away since it maps in a unique way to subType?

  • sino (unregistered) in reply to Consultuning
    Consultuning:
    Erm... my optimizing mind only can say... why is that nobody is not pointing that branching is mostly unnecessary? All that discussion about switch is puzzling, because the whole thing can be reduced to
    subType = mainType - 3 ;
    if( subType == 8 )
        ++subType;
    
    True, the original code does not alter the value of the subType if mainType is outside the 7,9,11 range. Let's add another twist, assuming that mainType is an integer
    if( mainType > 6 && mainType < 12) {
        subType = mainType - 3 ;
        if( subType == 8 )
            ++subType;
    }
    
    This is in my mind way more legible and does exactly the same. Or I'm completely confused?

    If the code was about mapping arbitrary mainType values to subType values, then a lookup table would be better, by the way.

    Holy Troll, Batman!

    You started out with a full TopCod3r treatment on causation and correlation, but you slipped up at the end there with the cromulent bit about 1st order lookup... still, full marks!

  • (cs) in reply to Laughing Jack
    Laughing Jack:
    frits:
    Any procedural solution for what this code is attempting would be smelly. However, I must say this is probably one of the ugliest ways to do it.
    So, how would you impliment what should be a simple switch statement? Recursively? Or perhaps you'd write a class just to encapsulate this switch?

    Congratulations, you're TRWTF.

    I'd suspect you of trolling, if it wasn't for use of the term TRWTF, which usually indicates lack of savvy. Therefore I'll indulge this question. Most branching can be eliminated in OOP languages through use of polymorphism. Any procedural approach, including a hashtable, requires the original code to be rewritten anytime new "types" are added or existing "types" are changed. Using polymorphism allows new code to be written that fufills the original design contract, but does not require rewriting and possibly breaking existing code.

    BTW- this concept is pretty basic OOD.

  • ClaudeSuck.de (unregistered)

    BTW why does nobody talk about the FILE_NOT_FOUND option?

  • AdT (unregistered)
    Rob added, "all I can figure is that the developer honestly didn't know that there is such a thing as 'else if'.

    There is no such thing as an 'else if' in the C++ standard. An 'if' statement can have an else clause containing a statement, which could just happen to be another 'if' statement. Likewise, the grammar does not directly address the use of blocks for any of 'if', 'for', 'while' or 'do-while'. Instead, the statement(s) governed by these compound statements could just happen to be block statements. A little known but occassionally useful feature of the language is that you can use block statements independently of the above-mentioned constructs, e.g. for controlling variable lifetime.

    (I wrote a C parser once and can't help being a C/C++ wise guy.)

  • RabiDawg (unregistered) in reply to Zylon
    Zylon:
    Consultuning:
    Erm... my optimizing mind only can say... why is that nobody is not pointing that branching is mostly unnecessary? All that discussion about switch is puzzling, because the whole thing can be reduced to
    subType = mainType - 3 ;
    if( subType == 8 )
        ++subType;
    
    There's a special place in Maintenance Hell for coders like you.
    Just look at this username. That should explain it. I bet he/she is filthy rich with code like that. Don't hate!
  • Ouch! (unregistered) in reply to AdT
    AdT:
    A little known but occassionally useful feature of the language is that you can use block statements independently of the above-mentioned constructs, e.g. for controlling variable lifetime.
    Little know feature? Does that mean I can upgrade my C rating from "not entirely clueless" to "wizard" because I knew the feature from day one?
  • (cs) in reply to ClaudeSuck.de
    ClaudeSuck.de:
    BTW why does nobody talk about the FILE_NOT_FOUND option?
    Easy: Most embedded systems don't have a file system.
  • Laughing Jack (unregistered) in reply to frits
    frits:
    Laughing Jack:
    frits:
    Any procedural solution for what this code is attempting would be smelly. However, I must say this is probably one of the ugliest ways to do it.
    So, how would you impliment what should be a simple switch statement? Recursively? Or perhaps you'd write a class just to encapsulate this switch?

    Congratulations, you're TRWTF.

    I'd suspect you of trolling, if it wasn't for use of the term TRWTF, which usually indicates lack of savvy. Therefore I'll indulge this question. Most branching can be eliminated in OOP languages through use of polymorphism. Any procedural approach, including a hashtable, requires the original code to be rewritten anytime new "types" are added or existing "types" are changed. Using polymorphism allows new code to be written that fufills the original design contract, but does not require rewriting and possibly breaking existing code.

    BTW- this concept is pretty basic OOD.

    So, you don't know what the types are types of, or the context of this code, or if there is an existing object model, and you could tidy this up with a switch statement in less than a minute, but you're already sure you want to rewite this as part of a new object model. I imagine they didn't mention "premature optimization" or "KISS" in college did they?

    You sure have put a grin on my face. Thanks :-)

  • Dan (unregistered)

    It looks like he also never heard of 'switch'

  • Ouch! (unregistered) in reply to Dan

    No, it's EVE online!

  • Main Switch (unregistered)

    What do you mean else... if? Isn't this a switch?

    switch(mainType) { case(7): subType = 4; break; case(9): subType = 6; break; case(11): subType = 9; break; default: break; } </ code>

    BTW is it possible to indent code in this forum?

  • Dweedle (unregistered) in reply to dkf

    ... or if it is a global variable written to by another thread?

  • Dweedle (unregistered) in reply to dkf

    The real WTF is that there's no way to switch this to a threaded view.

  • (cs) in reply to Main Switch
    Main Switch:
    What do you mean else... if? Isn't this a switch?
    switch(mainType)
    {
    case(7):
        subType = 4;
        break;
    case(9):
        subType = 6;
        break;
    case(11):
        subType = 9;
        break;
    default:
        break;
    }
    

    BTW is it possible to indent code in this forum?

    Sure. Didn't you notice the link BBCode Okay right above the edit box?
  • onaka (unregistered) in reply to FriedDan

    maybe this is built on some de compiled auto generated code ive seen such soluions in this type of code

  • Chris (unregistered)

    We came across one even worse. Not so much as an 'else' statement in sight.

    if (x) ...code...

    if (!x) ...code...

  • JimTheJam (unregistered)

    For everyone who thinks switch/case statement are extremely superior to if-else construct (in this situation):

    In the olden days (and maybe still) the case/switch statement checks the controlling variable against the lowest value, then checks against the highest value, then does an indexed GOTO using a table <<minor and major implimentation variations, depending upon your particular compiler and hardware>>

    The resulting code is longer, slower, and more buggy (yes, I'm an old timer), than the nested if-then-else-if.

    As a result most coders only used the case/switch statement for situations where the overhead was small compared to the many if tests. AND, as a result, it was a little confusing to someone who came across a two or three element case/switch statement -- so for maintenance, case/switch statements where there were lots of cases, such as apply productions in a parser.

    The "obviousness" of the switch statement vs the cascading if-then-else construct is in the eye of the beholder -- and the particular group you are working for/in.

    I would think a case of three would give me more pause than a three level nesting -- in this particular situation.

    In the olden days the code space was definitely a consideration. Of course in an embedded system ...

  • Quirkafleeg (unregistered) in reply to Seminymous Coward
    Seminymous Coward:
    do {
       blablabla-with-some-breaks;
    } while (false);
    is a terrible way to write
    {
       blablabla-with-some-breaks;
    }
    .
    while (contractor != idiot) {
      /* stunt ship */
      {
        /* you have been diverted */
        break;
      }
      /* aargh too soon */
    }
    … agreed.
  • SoaperGEM (unregistered) in reply to Eli
    Eli:
    Yeah, this code sucks. He should have used do { ... } where (false) so he didn't have to break at the end!

    CAPTCHA: nulla - stereotypical Italian undefined value.

    Obviously you're being sarcastic here, but a do-while-false isn't necessarily a bad thing--provided there's a lot more in there than just those 3 if statements. If you had many, many, many lines of mostly disjoint validation routines (i.e. else if's wouldn't cut it), it might be useful to be able to use the break to jump to the end once you've reached some condition. It's essentially emulating a limited goto, which could be used properly.

    CAPTCHA: genitus. Sounds like some weird STD.

  • Quirkafleeg (unregistered) in reply to r3jjs
    r3jjs:
    If this code:
    do { /*code here*/ } while (0);
    was used in a #define, than considering the while(0) to be boilerplate doesn't bother me.
    But the trailing ‘;’ in the #define is just plain broken: you'd have to remember to omit the semi-colon wherever you use the macro;; else you'll get errors.
    Easier than trying to remember the rules of when you do and do not need it.
    I've yet to find a situation in which I do and do not need it…
  • Quirkafleeg (unregistered) in reply to Chris
    Chris:
    We came across one even worse. Not so much as an 'else' statement in sight.
    if (x)
        ...code...
    if (!x)
        ...code...
    It could be that the first ‘if’ block contains code which modifies x…
  • Coder (unregistered) in reply to SoaperGEM
    SoaperGEM:
    ... Obviously you're being sarcastic here, but a do-while-false isn't necessarily a bad thing--provided there's a lot more in there than just those 3 if statements. If you had many, many, many lines of mostly disjoint validation routines (i.e. else if's wouldn't cut it), it might be useful to be able to use the break to jump to the end once you've reached some condition. It's essentially emulating a limited goto, which could be used properly.

    In this year (2010), even the C compilers have been mostly upgraded to optimise if-else constructs and switch constructs as well as you can. If you had many, many, may lies of omstly disjoint validation routines, the compiler will generate a jump to the end once you've reached some condition.

    Have a look at the code your compiler generates to see what your compiler thinks is the best code to generate for different ways of writing this.

    (I do look at the generated code, because the targets I have don't have file systems)

  • Brian Manahan (unregistered) in reply to Laughing Jack

    frits is right -- throwing a bunch of if/else statements together is usually a hackish way to do things. We don't know if there's a viable way to OO this, but if there is, it would be way better than an ugly if/elseif/elseif/etc/etc.

  • (cs) in reply to Ahruman
    Ahruman:
    Consultuning:
    if( mainType > 6 && mainType < 12) {
        subType = mainType - 3 ;
        if( subType == 8 )
            ++subType;
    }
    
    This is in my mind way more legible and does exactly the same. Or I'm completely confused?
    Two ifs? How abhorrently sloppy. Won’t someone _please_ think of the branch predictors!
    const int LUT[16] = { 16, 16, 16, 16, 16, 16, 16, 4,
     16, 6, 16, 9, 16, 16, 16, 16 };
    int val = LUT[mainType & 15];
    int isRemapped = !(mainType &~ 15) &~ (val >> 4);
    subType = subType & isRemapped - 1 | val & isRemapped * 15;

    Before I found your contribution, I came up with the snippet below. I think it's superior:

    const int STM[16] = { 0, 1, 2, 3, 4, 5, 6, 4, 8, 6, 10, 9, 12, 13, 14, 15 };
    int a = (((a = mainType >> 4) | -a) >> 63);
    subType = (a & mainType) + ((~a) & STM[mainType & 15]);
    
    

    Harder to understand is the goal, right?

  • André Laszlo (unregistered)

    Challenge accepted. This must be the best way to do this:

    int mainType(int x) { return x&x<<2&8|x>>3&x>>1&1|x<<1&x>>1&4^4|~x&2; }

    ;D

  • Keith (unregistered) in reply to frits

    errr.....

    nowhere does it say what the type is of mainType or subType...

    it would be perfectly reasonable in the land of WTF to override the == operator and the = operator so that

    == on mainType could == 7 9 and 11 at the same time

    and = on subtype could potentially add something to a colllection.... which then can be used with an == to see if its in that collection ;)

    operator overloading makes things fun.... heck the operation of == in operator overloading WTF land could accumulate the value also! :)

    so most of the rewrites in this thread wouldn't work if that was the case, most are just assuming its an int (which it most likely is, but hey )

  • Laughing Jack (unregistered) in reply to Brian Manahan
    Brian Manahan:
    frits is right -- throwing a bunch of if/else statements together is usually a hackish way to do things. We don't know if there's a viable way to OO this, but if there is, it would be way better than an ugly if/elseif/elseif/etc/etc.
    According to what criteria of "better"? "Uses objects" perhaps?

    I understand that there is a school of OO thought that states every branch should be replaced by an object. It's a little bit of an understatement to say that not everyone agrees with this degree of object-fetishism.

  • (cs) in reply to Brian Manahan

    Shh. Don't scare the code monkey. All this talk of OO is making him feel threatened.

  • (cs) in reply to Laughing Jack
    Laughing Jack:
    So, you don't know what the types are types of, or the context of this code, or if there is an existing object model, and you could tidy this up with a switch statement in less than a minute, but you're already sure you want to rewite this as part of a new object model.

    Nice run-on sentence. I notice you didn't actually address my reasons for suggesting a switch or other procedural construct is the wrong strategy. I never said I would rewrite anything. I would have never written this way in the first place. Remember: Design first, code second.

    Laughing Jack:
    I imagine they didn't mention "premature optimization" or "KISS" in college did they?

    I learned OO on the job, not college. Did you go to college? I suspect you wouldn't know how to go about doing this using Polymorphism. You write a base class that implements most of the logic. Then you create simple classes that customize or extend the base class. It's really simple.

    Laughing Jack:
    You sure have put a grin on my face. Thanks :-)

    Feeling superior and being superior are not always the same thing.

  • foxyshadis (unregistered) in reply to Spoe
    Spoe:
    Why not:
    tmp = 0xF;
    switch (mainType) {
        case 7:
            tmp ^= 0x2;
        case 9:
            tmp ^= 0xF;
        case 11:
            subType = tmp ^ 0x6;
            break;
    }
    You are my new hero.
  • Herby (unregistered) in reply to Zylon
    Zylon:
    Consultuning:
    Erm... my optimizing mind only can say... why is that nobody is not pointing that branching is mostly unnecessary? All that discussion about switch is puzzling, because the whole thing can be reduced to
    subType = mainType - 3 ;
    if( subType == 8 )
        ++subType;
    
    There's a special place in Maintenance Hell for coders like you.
    No, it is a special place in WTF land. Especially if you need to add a new value.
  • Zapp Brannigan (unregistered) in reply to dkf
    dkf:
    halcyon1234:
    Else if and switch sound good, but what are you going to do when mainType == 7 AND mainType == 9, huh?
    That could actually be possible if it was a volatile variable that is tied to some piece of memory mapped hardware. But I'd rather not think about that.
    Like in an embedded system.
  • (cs)

    subType = (mainType==7)?4:(mainType==9)?6:(mainType==11)?9:FileNotFound;

Leave a comment on “Else... where?”

Log In or post as a guest

Replying to comment #:

« Return to Article