• DoomPope (unregistered) in reply to Anon

    if(mainType == 7 || mainType == 9) subType = mainType - 3; else subType = mainType -2;

    Done.

  • xeno (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.

    tl;dr

    You know, without getting into a debate about OO Design Patterns, there don't seem to be a lot of other commentators who're suggesting a similar approach to yours. When that sort of thing happens to me, I re-examine my assumptions - it's usually because I'm barking up the wrong tree.

  • eli (unregistered)

    obviously, the code should have been something readable like:

    subType = ((mainType%7)/2)*((mainType%7)/2) + 3

  • (cs) in reply to Annon
    Annon:
    Quirkafleeg:
    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.
    An extra ; in C/C++ code is just an empty statement. You might want to try it out some day. A coworker of mine recently had some great fun in C# with if(...);{...}, wondering why the {...} block always executed.
    Oh, so close! You almost gave an example of why one should avoid leaving a terminating semicolon in a macro statement.

    An example

    if (foo) if (bar) MACRO else { ... }

    Just consider the effect of that code with and without the terminating semicolon in the do { ...} while() macro.

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

    Well that's just, like, MY opinion, man. Why would you care?

    tl;dr

    That's hard to believe.

    You know, without getting into a debate about OO Design Patterns, there don't seem to be a lot of other commentators who're suggesting a similar approach to yours. When that sort of thing happens to me, I re-examine my assumptions - it's usually because I'm barking up the wrong tree.

    Thanks for the unsolicited advice, kindly old troll.

    A large number of developers are either clueless, lazy, or both. This is compounded by the fact that most of the comments on this site are either completely sarcastic or pedantic. Thus, having a minority opinion is usually a good thing IMO. Also note that my original comment was posted early and not targeted at anyone else's comment. Seems odd to me that it would get such a rise out of anyone.

  • (cs) in reply to frits
    frits:
    Just procedural?

    Meh... maybe I read your post wrong when I replied???

    frits:
    Any procedural solution for what this code is attempting would be smelly

    The mention of the paradigm implies that there is some sort of relation (causation/correlation) between it and this particular code snafu. Or maybe I'm reading your post wrong or reading too much into it, I dunno.

  • xeno (unregistered) in reply to frits
    frits:
    Thanks for the unsolicited advice, kindly old troll.

    A large number of developers are either clueless, lazy, or both. This is compounded by the fact that most of the comments on this site are either completely sarcastic or pedantic. Thus, having a minority opinion is usually a good thing IMO. Also note that my original comment was posted early and not targeted at anyone else's comment. Seems odd to me that it would get such a rise out of anyone.

    A large number of programmers are also egomaniacs who've forgotten the meaning of the word "hubris", if they ever knew it in the first place. What makes you better than all the rest of us egomaniacs, hmmm?

  • Enormous Jack (unregistered) in reply to xeno
    xeno:
    A large number of programmers are also egomaniacs who've forgotten the meaning of the word "hubris", if they ever knew it in the first place. What makes you better than all the rest of us egomaniacs, hmmm?
    This one still ticking?

    Walk away man, the guy's a zealot who only knows one the one true way, and he'll just taunt you into a pissing contest like he did calling me a n00b. You might as well argue about what constitutes a balanced diet with a dog, you'll only get "meat, meat, meat, meat, meat, sausages, puke, meat" from now to doomsday.

  • someone (unregistered)

    This guy is stupid and ignorant. Using only the NAND gates is NOT wasteful. And I guess he hasn't seen the construct while(false) {...} either.

  • xeno (unregistered) in reply to Enormous Jack
    Enormous Jack:
    xeno:
    A large number of programmers are also egomaniacs who've forgotten the meaning of the word "hubris", if they ever knew it in the first place. What makes you better than all the rest of us egomaniacs, hmmm?
    This one still ticking?

    Walk away man, the guy's a zealot who only knows one the one true way, and he'll just taunt you into a pissing contest like he did calling me a n00b. You might as well argue about what constitutes a balanced diet with a dog, you'll only get "meat, meat, meat, meat, meat, sausages, puke, meat" from now to doomsday.

    I guess you're right, typos notwithstanding. I'll quit kicking the dog.

  • GayLord (unregistered) in reply to quisling
    quisling:
    frits:
    blah blah blah GIGANTIC!!!
    Laughing Jack:
    blah blah blah ENORMOUS!!!
    Quick, everyone, gather round! frits and Laughing Jack are about to whip out their Senior Programming Penii!!! (Penises? sp? gr?)

    ...

    gtfo||stfu pls; kthxbai.

    Why, *Hello* Boys

    (shutup quisling you cockblocking bastard)

  • Peter Lawrey (unregistered)

    Risking a trigraph.

    subType = mainType == 7 ? 4 : mainType == 9 ? 6 : mainType == 11 ? 9 : subType;

  • Brainfucker (unregistered) in reply to Andrea D'Alessandro

    While loops are all that's ever necessary.

  • (cs) in reply to BBT
    BBT:
    "so he cobbled together an 'else if' in the most ridiculous way possible."

    That sounds like a challenge. I'm sure someone here could do more ridiculous!

    Happy to oblige:

    subType = 
        ((mainType == 7) ? 
        4 : 
        ((mainType == 9) ? 
        6 : 
        ((mainType == 11) ? 
        9 : 
        subType
        )));
    
  • (cs) in reply to Peter Lawrey
    Peter Lawrey:
    Risking a trigraph.

    subType = mainType == 7 ? 4 : mainType == 9 ? 6 : mainType == 11 ? 9 : subType;

    Ack! Duped! Didn't see this one before I posted mine. Two notes though:
    1. "Ternary Operator" != "Trigraph" -- I used to think so too (knew the operator, saw the word, and assumed that was what it meant), but it turns out a trigraph is something completely different http://en.wikipedia.org/wiki/Digraphs_and_trigraphs#C

    2. Much as I love (ab)using ternaries (and I do), I'd be terrified to try it without parentheses. Too lazy to check for myself -- does the above actually work, precedence-wise? Word of warning: C's operator-precedence rules may provide nearly complete DWIM support, but (a) "nearly" is such a troublesome word, and (b) it can be even worse in other languages. E.g., I was re-impressed with the wisdom of defensive parenthesization after I got bit -- hard -- using a ternary with PHP's dot operator.

  • (cs) in reply to Ed
    Ed:
    But what if mainType is 7, 9 AND 11? Then you're just screwed!

    Geez... why is everybody getting so worked about that scenario. "Alternate universe" this, "quantum" that, "parallel" the other.

    The answer is obvious. If mainType is 7, 9, AND 11, then subType is 4, 6, AND 9.

    You're welcome.

  • Acrimonious Coward (unregistered)
    Consultuning:
    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?

    Yes, I think you are confused, what about if mainType is 8 or 10?

    if( mainType > 6 && mainType < 12 && mainType % 2 == 1) {
        subType = mainType - 3 ;
        if( subType == 8 )
            ++subType;
    }
    

    There, fixed that for ya!

  • Mike (unregistered)

    Everyone using anything else than fortran is a sad unusefull looser, anyway.

  • Bear (unregistered)

    My whole job is bumming code for speed (Yes, there are a few of us left). I use a profiler to identify hotspots, bum the heck out of inner loops that run hot, and sometimes recommend or do code reorganizations for algorithmic efficiency.

    One of the special bits of knowledge that my job requires is the cost of branching. Instruction cache misses can cost more than a whole lot of expression evaluation. And even if you do have it in cache, you've spent extra time on the instruction fetch cycle that other threads probably needed. So if I found this code in the middle of a hot loop, I would replace it with:

    subType = mainType - 3 + (mainType == 11);

  • Deadcode (unregistered) in reply to Quirkafleeg
    Quirkafleeg:
    Deadcode:
    if (mainType & (mainType-7 < 5u))
        subType = mainType + ((mainType-18)>>2);
    Let's see… we can ignore the first condition, since (unsigned)(0-7) > 5u…
    	SUB	a1,v1,#7
    	CMP	a1,#5
    	SUBLO	v2,v1,#18
    	ADDLO	v2,v1,v2,ASR #2
    TEH WINNAR! (Unless subType is unsigned…)
    Notice I used bitwise AND, not logical AND! Thus you have omitted part of my code from your ARM assembly which was important in achieving semantic equivalence with the original code.
    Bear:
    My whole job is bumming code for speed (Yes, there are a few of us left). I use a profiler to identify hotspots, bum the heck out of inner loops that run hot, and sometimes recommend or do code reorganizations for algorithmic efficiency.

    One of the special bits of knowledge that my job requires is the cost of branching. Instruction cache misses can cost more than a whole lot of expression evaluation. And even if you do have it in cache, you've spent extra time on the instruction fetch cycle that other threads probably needed. So if I found this code in the middle of a hot loop, I would replace it with:

    subType = mainType - 3 + (mainType == 11);

    Cool that you actually get to do that as a job in itself.

    However your code is not semantically equivalent to the original code, which didn't make any assignment to subType if mainType was not in {7, 9, 11}. Good luck eliminating the conditional branch while maintaining semantic equivalence! Here's my try:

    subType += (mainType + ((mainType-18)>>2) - subType) & -(mainType & (mainType-7 < 5u));

    Or if you prefer your formula:

    subType += (mainType - 3 + (mainType == 11) - subType) & -(mainType & (mainType-7 < 5u));

  • zahlman (unregistered) in reply to Alan
    Alan:
    Pfft. You C guys and your silly switch statements. All we really need is a map!
    types = {
        7: 4,
        9: 6,
        11: 9,
    }
    

    if baseType not in types: return None

    return types[baseType]

    Python FTW!

    (of course it'd be better to avoid the magic numbers altogether, but we don't seem to have that luxury here)

    Ugh.

    subType = {7: 4, 9: 6, 11: 9}.get(baseType, None)

  • kili (unregistered) in reply to frits
    frits:
    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?)

    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.

    Not at all if mainType is a Foo, with Foo defined as following...

    class Foo { public: int operator==(int x) { return 1; } };

  • (cs)

    yo I'm really happy to hear about your switch statements, and I'm gonna let u finish, but really Rob B had the best solution ever!

  • x86 CPU (unregistered)

    If mainType and subType are integers and if there is no funny C++ overload of operators, the optimal x86 assembler equivalent for that code would be:

    ;	eax = mainType
    ;	edx = subType
    ;	ecx = scratch subtype
    
    	lea	ecx, [edx - 2]
    	cmp	eax, 11
    	cmoveq	edx, ecx
    	dec	ecx
    	cmp	eax, 9
    	cmoveq	edx, ecx
    	cmp	eax, 7
    	cmoveq	edx, ecx
    
  • Scott (unregistered)

    Uh, actually I think he cobbled together a switch...

  • JimTheJam (unregistered) in reply to DWalker59

    Not "not possible". Just a little more complex than I bothered to describe. The compiler built (internally) as large a table as it could, and if values larger that the table size existed, it made more tables. In each table it would prune back the starting and ending elements of that table which had no values before emitting the tables. In your example it would have eventually emitted a table for 100 entries, then built another table with one entry -- 59087. Actually, it was a 16 bit computer and the index had to be positive integers (if I recall correctly), so the maximum value was 32767. So 59087 would have been an error, but that's beside your point.

    The empty entries had zeros, which either the switch code checked for, or caused the computed goto to drop through and then branch to the end of the statement, I forget which. Having sparse switch/case numbers was another reason to avoid the construct (program and data space were not large), but the code (tended) to work. For a set of values which was large, mostly incremental, and not too sparse it works well. That compiler is still used, not for new projects, but for supporting old code in old emulated programs running on a (newer) 32bit machine.

    Warning: this is an old memory from an old brain. Veracity is not guaranteed. It is true as far as I remember, but I'm not sure how much I trust it. For example, it is possible that the programmer had to do the splitting up if there were too many cases instead of the compiler.

    Ah, the olden days. When men were men, and real programmers knew the assembly code the compiler emitted. Just after the days when real men used 1's and 0's -- and not too many of those.

  • JimTheJam (unregistered) in reply to JimTheJam

    Re: Not "not possible".

    Previous submittal about switch code. I should have included some of the reply I was reply'ing to. It was in response to DWalker59's reply to my description of olden days switch/case statement implementation. He stated that:

    "That is not possible unless the values are regularly spaced. If the values are 1, 2, 3, 4, 100, 59087, then an indexed Goto would not work"

    To which I wrote my above opus.

    Sorry for not using the "quote" button.

  • bundyxc (unregistered)

    Code snippets need to be included in resumes. That way if you get a bad coder, you know it before you send him off to work on your important projects.

  • Old Timer (unregistered)

    That's awful, but the (slightly) better solution would be a switch not a series of "else if" blocks; that would be clearer and idiomatic for C++ whilst also bypassing unnecessary code (not that it's a heavy penalty in this case).

    Whoever wrote that code, though, was smoking something.

  • BXB (unregistered) in reply to pete

    The loop exits after one execution so... nothing.

  • Kathar (unregistered) in reply to apaq11

    If you want to otimize your circuit, you need NAND, NOR and NOT. NOT and NOR can be implemented using NAND, but it's not optimized any more (NOT = 2 transistors, NOR & AND = 4 transistors. You need one NAND for a NOT and 3 NANDs for a NOR)

    AND and OR are implemented with a NAND/NOT followed by a NOT, and therefore used only when they cannot be replaced by NAND/NOR.

  • The M (unregistered) in reply to FriedDan

    fix'd:

    subType = mainType - 3; if (mainType == 11) subType--;

  • casey (unregistered)

    The reason to use only NAND gates (or NOR gates..) in a cpu would be to reduce the cost of producing them. It is cheaper to produce a ton of NAND gates and put them into a chip then it is to produce AND, OR, and NOT gates and put them onto the chip.

  • qwe (unregistered)

    Dofus Kamas|Prix Moins Cher Dofus Kamas|Kamas par allopass|Dofus kamas audiotel|Dofus kamas par telephone sur Virstock.com

    Meilleur prix www.virstock.com dofus kamas stock de www.virstock.com dofus kamas

    Prix moins cher www.virstock.com dofus kamas vente www.virstock.com dofus kamas sur www.virstock.com

    www.virstock.com/jsp/comments.jsp dofus kamas vente www.virstock.com

  • Jimothy (unregistered)

    That sounds like Prof Ayatollah at Purdue.

  • JavaGuru (unregistered)

    Why not use the mighty try/catch combination ...

    try { if(mainType==9) { subType = 4; throw new Exception(); } ... } catch(Exception e) {

    }

  • matt (unregistered)

    i just wrote one of those in php. the code came out much clearer that way :)

  • oksupra.com (unregistered)

    Supra shoes are so popular all over the world. Whatever you take on Supra being in the Supra Skytop Shoes market. Now Supra Strapped Shoes also very popular attention. It is nice that they actually took the time to make Supra Skate Shoes that work well. Supra shoes is a brand that has been inspired, designed and marketed by passionate individuals. We have brought to you the fullest selection of Supra footwear at cheapest price. Overload Skateshop carries a wide range of Supra Shoes to fit your 9-stair kickflips.

  • Justin (unregistered)

    This code is much more readable than a splodge of nested if then elses

  • Justin (unregistered)

    IMHO I think that break at the bottom of the code must be an error. This thing is suppose to loop until one of those conditions comes true. From a maintenance point of view this code is easier to change if there are new conditions to break this loop.

  • Sergejack (unregistered)

    There might be a good reason to write the code like this: to limit the indentation.

    for(;;) // better looking than while(true) { if (condition 1) break; do something 1; if (condition 2) break; do something 2; if (condition 3) break; do something 3; break; // don't forget about that one }

    is more compact and more readable (imho) than

    if (not condition 1) { do something 1; if (not condition 2) { do something 2; if (not condition 3) { do something 3; } } }

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

Log In or post as a guest

Replying to comment #:

« Return to Article