• (cs) in reply to joodie
    joodie:
    <snip>
    I would not be terribly surprised if a compiler translated

    for (i=0; i <10;i++) {
      i++;
    }

    to (pseudocode):

    int i=0;
    LOOP:
    if (++i < 10) {
      int some_var = i;
      some_var++;
      goto LOOP;

    }

    </snip>



    No, it's more like this:

    i = 0;
    LOOP:
    if(i < 10) {
       i++;
       i++;
       goto LOOP;
    }

  • (cs) in reply to igor1960
    Anonymous:

    Here I agree -- MO screews everything.

    Modus Operandi screews everything, huh?

    Anonymous:

    However, your criticism an claim that original code was stupid hypothetically may not be the case. In fact it may not be as stupid as it looks like.

    Just imagine that String class is not really string class as we understand it -- maybe it's more complicated then just string and which is more important it just can't be initialized by just "" object (let's assume it's a structure having 100 members that are filled based on time of day passed).

    I don't see what this fantasy you are describing has to do with anything.

    Anonymous:

    Or, In addition -- that class could be implemented just as a singleton (or maybe it just a proxy to singleton) -- So, any declarative initialization described as a "proper solution" will initialize real singleton to "Sunday"? Isn't that what we want?

    I'm not sure what you are on about.  Do you not understand what the code does?  That it's in a loop is meaningless.  It doesn't change the effect of the code no matter what class String is or whatever it is that you are saying.

    Anonymous:

    So, my point is: it's always much efffortless to criticize -- this criticizm doesn't pay your bills though.

    It doesn't cost anything either.

  • Stoyan (unregistered) in reply to Andy

    No, it's not the same, although very close:

    String[] days = new String[] { "Monday", ... };

  • igor1960 (unregistered) in reply to dubwai

    Again it's all hypothetical, but even iteration: what if  int operator= or ++ are/is overloded. The whole thing is stupid and of course "bad programming practice", but just to state that "loop is meaningless" -- for sure you could...

  • (cs) in reply to igor1960

    Anonymous:
    Again it's all hypothetical, but even iteration: what if  int operator= or ++ are/is overloded. The whole thing is stupid and of course "bad programming practice", but just to state that "loop is meaningless" -- for sure you could...

    If any of the above were true it would be even worse than what it appears to be.  The language is not listed, but if it is Java, none of that could be true.  Which reminds me why it's a good thing Java doesn't allow overloaded operators.

  • (cs) in reply to igor1960
    Anonymous:
    No, it's not the same, although very close:

    String[] days = new String[] { "Monday", ... };

    I don't get your meaning.  Assuming again that this is Java,

    String[] days = new String[] { "Monday", ... };

    String[] days = { "Monday", ... };

    Are completely equivalent.

  • (cs) in reply to Blue
    <font size="3">I recognize this too as sarcasm.  Perhaps I can develop the ability to recognize it after all!  There IS hope for me yet!
    </font>
    <font style="font-family: georgia;" size="3">
    Well done, Blue!  You'll be a sarcastic old row-of-asterisks like me before you know it!

    (PS What is going on with this forum software?  Indenting isn't working either?  Is anyone else finding that the formatting buttons are as useless as *** on a bull at the moment?)
    </font>
  • (cs)

    Exhibit B has a number of possible reasonable interpretations.

    Perhaps a sequence of operations might be generate an execption and some way of knowing where this occurred was needed (the value of i provides such
    information).

    Perhaps an earlier version of this code contained code that was executed
    inside the for loop but before/after the switch statement.  Subsequent changes
    to the code resulted in these statements being deleted.  The maintenance
    programmer is likely to take the path of least work and leave the for/switch as-is.

  • (cs) in reply to igor1960
    Anonymous:

    The problem with that thread is: looks like you all here has nothing else to do but to demonstrate how stupid others are.

    I'm not new in programming and trust me put alot of stupid things in my code and was paid "by lines" and/or "by time" and/or "by output" and/or "by speed" and etc. during my career.

    I understand the reason you may laugh at presented samples, but trust me -- your laugh has nothing to do with the real "brush fire extinquishing" you have to deal with sometimes in your everyday programming life. So, kindly excuse me, but there is no reason to joke about somebodies bad programming practices.

    On the other hand and being serious here: whatever language you choose -- I agreee you saved somespace in not typing that "laughable" switch statement and not confusing others, but instead used specific language/compiler feature and just use declarative approach -- end result is still the same: "During runtime equivalent of that long case was executed"... So, what exactly are you laughing about?!...

    That entire post was a joke, right?  

  • (cs) in reply to Ron
    Anonymous:

    An awesome piece of c hackery on top of it, implementing coroutines:

    http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html


    Horribly confusing. If your context allows for a FIFO data structure that's efficient enough to meet your needs, then it's much simpler to let the producing function run ahead of the consuming function, as in the following pseudocode:

    consumer() {
      while (1) {
        while (structure doesn't contain enough data for me to consume)
          producer();
        pull some data from the structure;
        if (EOF)
          break;
        do something with the data;
      }
    }

    producer() {
      push some data to the structure;
    }

    This way, the producer can push data in whatever size chunks are convenient for the producer's nature, and the consumer can pull data in whatever size chunks are convenient for the consumer's nature - so long as the structure won't overflow.

    In the particular example given, the producer would push up to 255 characters at a time, and the consumer would then pull 1 character at a time until the structure was empty again. Thus, a 255-character circular array would work, and would make reasonably efficient use of memory (257 bytes) and speed.

    I suppose there are contexts in which you can't spare 257 bytes, but I would sure hate to have to program for them!

  • Pax Diablo (unregistered) in reply to Gary Henson

    Then why not insert bits of code like (sorry for my C bias):

    switch(0) {
       case 0: {
          putchar ('\n');
       }
    }

    Pax.

  • bobzyeruncle (unregistered)

    That beats my 41+ case switch in an Action class ;-)

  • (cs) in reply to dubwai
    dubwai:

    Bustaz Kool:
    Has anyone ever really paid people 'by the line' of code?  The concept keeps getting mentioned (I assume facetiously) but I've never heard of it in real life

    I've know that a lot of managment types think it's a reliable way to measure developer productivity.  More code == bigger raises and more clout.  It might explain all the copy / paste code I see.



    I have managed development teams, and I find that lines of code is an excellent metric. Only most managers seem to measure it backwards, and think that the team is being more productive when it's going up, rather than down.

  • (cs)


    const int nLimits = 256;
    for( int i = 0; i < nLimits; ++i )
    {
    switch( i )
    {
    case 0:
    ProcessInternalFindings();
    break;

    case 1:
    break;

    <font> </font>case 2:
    BuildReferences(8,nRef);
    break;

    //ED: Snip 2-254

    case 255:
    CleanAllocations();
    break;
    }
    }


    Is this designed for adaptation in the future? Else why not just
    public void Execute256OtherFunctions(){
    ProcessInternalFindings();
    BuildReferences(8,nRef);
    ...
    CleanAllocations();
    }

    Or am I missing something here?

  • (cs) in reply to Michael Link
    Anonymous:
    Exhibit A is just dumb but doesn't cause much headache. I would send the developer to some training. Exihibit B is much more worse because probably the whole application is tangled in this for-switch-***. I never would allow the developer of this beast to write one line of code anymore until he has undergone some kind of Cobol exorcism.

    COBOL exorcism? You're inhumane!
  • (cs) in reply to V.
    V.:
    Is this designed for adaptation in the future?  Else why not just
    public void Execute256OtherFunctions(){
    ProcessInternalFindings();
    BuildReferences(8,nRef);
    ...
    CleanAllocations();
    }

    Or am I missing something here?



    You're missing "an extensible, highly performant way to serially execute a number of functions using an adaptable abstration layer to keep the virtualization data clean from object-oriented code block leakage and maintenence hazards through the use of highly portable lesser-known constucts of many languages." Yes, yes you are.

    joodie:
    <snip>
    I would not be terribly surprised if a compiler translated

    for (i=0; i <10;i++) {
      i++;
    }

    to (pseudocode):

    int i=0;
    LOOP:
    if (++i < 10) {
      int some_var = i;
      some_var++;
      goto LOOP;

    }

    </snip>



    As opposed to what, the hidden native for-loop instructions secretly built into every Intel chip and available only to paying ICL 8 "Pro Edition" customers? >_> There's no such thing as loops at the machine level, though the

    But you and the other guy are still wrong, because there's also no if blocks or anything like that. It'd go something like this:

    counter=10
    loop:
    i++
    i++
    counter--
    JUMP TO loop IF counter != 0

    (The last two instructions are sometimes grouped into a single LOOP IF counter != 0, with slightly different semantics.)
    It becomes:

    00400 MOV EAX,i
    00402 MOV ECX,10
    00405 INC EAX
    00406 INC EAX
    00407 DEC ECX
    00408 TEST ECX,ECX
    0040A JNZ 405

    (Testing something against itself returns its value to the next instruction.)

  • (cs) in reply to igor1960
    Anonymous:

    The only reason I've replyed was that as I undertsood the original joke placed at the beginning of the thread was to show that government workers are on break 7 days a week. Now, somehow thread moved into discussion of "programming practices".



    well, well. isn't this the same person who was responsible for this ?
  • mlk (unregistered) in reply to loneprogrammer

    C64 does that, but also a a renumber command.

  • (cs) in reply to foxyshadis
    foxyshadis:

    But you and the other guy are still wrong, because there's also no if blocks or anything like that. It'd go something like this:

    counter=10
    loop:
    i++
    i++
    counter--
    JUMP TO loop IF counter != 0

    (The last two instructions are sometimes grouped into a single LOOP IF counter != 0, with slightly different semantics.)
    It becomes:

    00400 MOV EAX,i
    00402 MOV ECX,10
    00405 INC EAX
    00406 INC EAX
    00407 DEC ECX
    00408 TEST ECX,ECX
    0040A JNZ 405


    If I had a compiler that mangled my loops that bad, I'd find its author, smash his computer to bits, then get a new compiler.
    I'd expect something more like
          mov eax, 0
    for: inc eax
          inc eax
          cmp eax, 10
          jl for

    The greatest amount of compiler psychic ability I could possibly accept is "add eax, 2" instead of two "inc eax". And even that would probably be a Bad Thing(tm).
  • g (unregistered) in reply to foxyshadis

    foxyshadis:
    V.:
    <SNIP>
    I would not be terribly surprised if a compiler translated

    for (i=0; i <10;i++) {
      i++;
    }

    to (pseudocode):

    int i=0;
    LOOP:
    if (++i < 10) {
      int some_var = i;
      some_var++;
      goto LOOP;
    }

    </SNIP>


    As opposed to what, the hidden native for-loop instructions secretly built into every Intel chip and available only to paying ICL 8 "Pro Edition" customers? >_> There's no such thing as loops at the machine level, though the

    But you and the other guy are still wrong, because there's also no if blocks or anything like that. It'd go something like this:

    counter=10
    loop:
    i++
    i++
    counter--
    JUMP TO loop IF counter != 0

    (The last two instructions are sometimes grouped into a single LOOP IF counter != 0, with slightly different semantics.)
    It becomes:

    00400 MOV EAX,i
    00402 MOV ECX,10
    00405 INC EAX
    00406 INC EAX
    00407 DEC ECX
    00408 TEST ECX,ECX
    0040A JNZ 405

    (Testing something against itself returns its value to the next instruction.)

    Umm, I don't think so. It should be:

    loop:
    i++
    i++
    JUMP TO loop IF i < 10

    Interestingly enough, for loops, the old Borland compilers (BC++ IIRC, been a while!) used to generate x86 of the form:

    <INIT variables>
    JUMP TO test
    loop:
    i++
    i++
    test:
    JUMP TO loop IF i < 10

    Presumably, this was to simplify the code generation. When in non-optimising mode, VS.Net 2003 C++ still does something similar. The following code:

    for(i = 0; i < 10; i++) {
    i++
    }

    generates:

    ; for(i = 0; i < 10; i++) {
     mov dword ptr [i], 0
     jmp test
    loop:
     mov eax, dword ptr [i]
     add eax, 1
     mov dword ptr [i], eax
    test:
     cmp dword ptr [i], 10
     jge loop_end
    ; i++;
     mov eax, dword ptr [i]
     add eax, 1
     mov dword ptr [i], eax
    ; }
     jmp loop
    loop_end:

    Of course, when compiled with optimisations on (max speed in my test), the compiler simply removes the loop as it doesn't do anything :). If you change it to have another line of j = i * 2;, the compiler generates:

    ; NB: ecx is used to hold j
    ; for(i = 0; i < 10; i++) {
     xor eax, eax
    ; i++;
    loop:
     add eax, 2
    ; j = i * 2;
     mov ecx, eax
     add eax, 2
     cmp eax, 14h
     jl loop

    The thing to note is how the compiler recognises that the add and check can be changed to 2 and 20 resepctively, and the use of registers. All part of the magic of optimisation :) (And I can remember the days when a cycle sheet was practically mandatory :), though that was my own code back on the 68000 :))

  • g (unregistered) in reply to g
    g:

    Interestingly enough, for loops, the old Borland compilers (BC++ IIRC, been a while!) used to generate x86 of the form:

    <INIT variables>
    JUMP TO test
    loop:
    i++
    i++
    test:
    JUMP TO loop IF i < 10

    Sorry, that should have been:

    i = -1
    JUMP TO test
    loop:
    i++
    test:
    i++
    JUMP TO loop IF i < 10

    It's *really* been a while! (You get the general idea anyway :))

  • (cs) in reply to zinglons_ale
    zinglons_ale:
    The greatest amount of compiler psychic ability I could possibly accept is "add eax, 2" instead of two "inc eax". And even that would probably be a Bad Thing(tm).

    Oh dear, better not turn your optimiser on.

    I just used that loop, with a following use of the loop counter in a function call, and the entire code resolved to a 'push 10' instruction.

  • (cs)

    <FONT face=Arial size=2>Call me crazy but for the first one if it is C# and is for the UI wouldn't you want to do something more like:</FONT>

    <FONT size=2><FONT face="Courier New">String[] days = </FONT><FONT face="Courier New" color=#0000ff>new</FONT></FONT><FONT face="Courier New" size=2> String[7];
    </FONT><FONT face="Courier New" size=2>System.Globalization.DateTimeFormatInfo culture =
       Thread.CurrentThread.CurrentCultureUI.DateTimeFormat;
    </FONT><FONT color=#008000><FONT face="Courier New" size=2>// As Sunday is 0 and Monday is 1
    </FONT></FONT><FONT size=2><FONT color=#008000><FONT face="Courier New">// But coder wants it to be Monday=0, etc. Sunday=6
    </FONT></FONT><FONT face="Courier New" color=#0000ff>for</FONT></FONT><FONT face="Courier New" size=2> (DayOfWeek day = DayOfWeek.Monday; day <= DayOfWeek.Saturday; day++)
    </FONT><FONT face="Courier New" size=2>{
    </FONT><FONT face="Courier New" size=2>days[day - 1] = culture.GetDayName(day);
    </FONT><FONT face="Courier New" size=2>}
    </FONT><FONT size=2><FONT color=#008000><FONT face="Courier New">// As Sunday is 0 and coder wants it to be 6
    </FONT></FONT><FONT face="Courier New">days[ 6 ] = culture(DayOfWeek.Sunday);</FONT></FONT>

    <FONT face="Courier New" size=2>The second example makes my mind boggle... [:|]</FONT>

    <FONT size=2><FONT face="Courier New"><FONT style="BACKGROUND-COLOR: #ffffff"><FONT color=#0000ff>case </FONT></FONT>1:
        <FONT color=#0000ff>break</FONT>;
    <FONT color=#0000ff>case </FONT>2:
        BuildReferences(8,nRef);
        <FONT color=#0000ff>break</FONT>;

    <FONT face=Arial>The <FONT face="Courier New"><FONT face=Arial>"</FONT><FONT face="Courier New">case 1:break</FONT></FONT><FONT face=Arial>" </FONT>is probablly to stop fall through, but why it isn't deleted in it entirity I guess we'll never know...</FONT></FONT></FONT>

    <FONT size=2><FONT face="Courier New"><FONT face=Arial>But as V. says why they didn't just write:</FONT></FONT></FONT>

    <FONT size=2><FONT face="Courier New">ProcessInternalFindings();
    BuildReferences(8,nRef);
    </FONT></FONT><FONT size=2><FONT face="Courier New"><FONT color=#008000>//ED: Snip 2-254
    </FONT>CleanAllocations();</FONT></FONT>

    <FONT size=2><FONT face="Courier New"><FONT face=Arial>Completely escapes me... [:O]</FONT>

    </FONT></FONT>
  • (cs) in reply to Rescendent

    Umm... the forum editor's quite cool with colour and formatting and everything, but doesn't seem to work so well...

  • (cs) in reply to Rescendent

    With a smaller font...

    Call me crazy but for the first one if it is C# and is for the UI wouldn't you want to do something more like:

    <FONT face="Courier New" size=2>String[] days = new String[7];
    System.Globalization.DateTimeFormatInfo culture =
       Thread.CurrentThread.CurrentCultureUI.DateTimeFormat;
    // As Sunday is 0 and Monday is 1
    // But coder wants it to be Monday=0, etc. Sunday=6
    for (DayOfWeek day = DayOfWeek.Monday; day <= DayOfWeek.Saturday; day++)
    {
         days[day - 1] = culture.GetDayName(day);
    }
    // As Sunday is 0 and coder wants it to be 6
    days[ 6 ] = culture(DayOfWeek.Sunday);</FONT>

    The second example makes my mind boggle...

    <FONT face="Courier New" size=2>case 1:
        break;
    case 2:
        BuildReferences(8,nRef);
        break;</FONT>

    The "case 1:break" is probablly to stop fall through, but why it isn't deleted in it entirity I guess we'll never know...

    But as V. says why they didn't just write:

    <FONT face="Courier New" size=2>ProcessInternalFindings();
    BuildReferences(8,nRef);
    //ED: Snip 2-254
    CleanAllocations();</FONT>

    Completely escapes me...

  • Brian (unregistered)

    I should probably submit this as a WTF, but I don't have the exact code anymore:

    bool b = whatever;
    ...
    switch (b) {
    case true: DoSomething();
    case false: DoSomethingElse();
    default: assert(0);
    }


  • (cs) in reply to igor1960
    igor1960:

    The problem with that thread is: looks like you all here has nothing else to do but to demonstrate how stupid others are.

    I'm not new in programming and trust me put alot of stupid things in my code and was paid "by lines" and/or "by time" and/or "by output" and/or "by speed" and etc. during my career.

    I understand the reason you may laugh at presented samples, but trust me -- your laugh has nothing to do with the real "brush fire extinquishing" you have to deal with sometimes in your everyday programming life. So, kindly excuse me, but there is no reason to joke about somebodies bad programming practices.



    Igor, I understand your point--we do all write stupid code.  However, I think you might misunderstand the spirit in which a forum like this is conducted.  In certain pursuits there is a tradition of learning from the kind of public roasting that's going on here.  What is understood but not said is that most of us would be equally willing to laugh at our own embarrassing mistakes.  Indeed, since I've been reading WTF, I've been making mental notes about the vast collection of potential submissions I could cull from my own work.


    So maybe lighten up, relax and enjoy the show.  No, it doesn't pay any bills, but if you can't spare the time from bringing home the benjamins, that's ok too.   I really don't have time to burn here either, but I do anyway--everybody has to have a hobby... haha.

  • Whim (unregistered) in reply to Andy
    Andy:
    kwatz:
    Duff's Device:
    http://www.lysator.liu.se/c/duffs-device.html


    Duff's device has to be one of the coolest abuses of C of all time.

    This is the second time in a week that I've read about Duff's Device. I /still/ don't "get it" -- how does it work? what the hell does it DO?

    update: while typing this, I went back and re-read the page, and now I think I get it. ::embarassed:: But, I'm not sure... anyone want to do an explanation of When You've Found It Useful? (and why)

    =D

  • igor1960 (unregistered) in reply to Rescendent

    What "escapes" you is the possibility that "i" maybe changing inside Snip 2-254...

    I'm not insisting that it is changing. And I'm not defending that ugly code, but the possibilty of "i" changing is very strong...

  • mjenks (unregistered)

    I still dont see whats wrong with any of this code!!

  • igor1960 (unregistered) in reply to Jeff S

    Jeff, "That entire post was a joke, right?":

    Why are you saying that? What's wrong with my post?

  • igor1960 (unregistered) in reply to matejcik

    "well, well. isn't this the same person who was responsible for this ?"

    Yes, that's me: so what? At least it works: what have you write recently?

  • (cs) in reply to mjenks

    Anonymous:
    I still dont see whats wrong with any of this code!!

    If you are not joking, step away from the computer.

  • (cs) in reply to igor1960
    Anonymous:
    "well, well. isn't this the same person who was responsible for this ?"

    Yes, that's me: so what? At least it works: what have you write recently?

    What exactly are you responsible for?  The ad?

  • (cs) in reply to Bustaz Kool
    Bustaz Kool:

    Sweets:
    Thats what happens when you pay people 'by the line'.

    Has anyone ever really paid people 'by the line' of code?  The concept keeps getting mentioned (I assume facetiously) but I've never heard of it in real life.



    It used to be very common, actually, especially in COBOL shops. Even in cases where it is not a formal policy, you still run into plenty of managers who see raw code output as a measure of productivity, even when the code is inefficient or even non-functional.

    Corpse-rat politics often encourages such wasteful practices. Larger projects, with more people and more lines of code, are more prestigious, so empire-building middle managers often pad projects at the expense of actually completing them. Since middle managers (in any company large enough to have them) are largely insulated from criticism - the blame for failure usually falls on either the upper management or on the rank and file - this can become a corporate cancer which is very difficult to eliminate once it has taken hold.
  • igor1960 (unregistered) in reply to dubwai

    dubwai , you for sure have a lot of extra available time to be involved with useless participation in weird discussions.

    The question is: what you gain from that? OK: we establsihed the code above is bad! So, go on with your life: Trust me: the life is too short  --I know -- this is my second life -- previous one I lived in India and worked for outsourced software company...

  • (cs) in reply to igor1960

    Anonymous:
    dubwai , you for sure have a lot of extra available time to be involved with useless participation in weird discussions.

    Apparently you also have the time.  It doesn't take long to post a comment though.  Do it while I'm waiting on processing.

    Anonymous:
    The question is: what you gain from that? OK: we establsihed the code above is bad!

    What do you gain from posting these replies?

    Anonymous:
    So, go on with your life: Trust me: the life is too short  --I know -- this is my second life -- previous one I lived in India and worked for outsourced software company..

    I don't know what that has to do with anything but if you think this is such a waste of time, why are you posting here?

  • Charles Nadolski (unregistered)

    Scoff all you want, but a switch statement inside a for loop can be very useful.  For instance, in the current project at work, there's a custom grid control, with the columns and their names predefined in stdafx (it makes it much easier to move a column due to a client's demands).  Now when building the grid, columns turn on and off depending on the analysis run.  So... there is a for loop that loops through all the column indices, with a switch loop inside for (almost) every column name.  Since certain columns are grouped with certain analyses, you can turn a bunch on an off at once.  The default switch is used for columns that are always enabled.  It's much easier to read this way and easier to move columns around in case something changes, things need to be removed, things need to be added, etc.  A laundry list of if/else statements going on for all nTotalCols would be IMHO worse code.  On top of that, switch statements are faster than if/else combinations.

    Example:

    for(nCol = 0; nCol<nTotalCols; nCol++)
    {

    switch(nCol)
    {
    //snip

    Col_Bart:
    Col_Homer:
    Col_Lisa:
    Col_Marge:
    Col_Maggie:
    if(nAlalysisType==THE_SIMPSONS)
    EnableColumn(true);
    else
    EnableColumn(false);
    break;

    //snip

    default:
    EnabledColumn(true);
    }

    And here's an example for text input from this C# program I'm working on.  Given, The order of commands in the text file is usually going to be PowerWord->Action->Purpose->Names.  But what if somebody decides to change their mind in the future and swaps Purpose with Names in the text file?  What if some moron put in a bunch of blank lines between [/PowerWord] and [Action]? It's one less function to change/debug.

                while ((strRead = fileInput.ReadLine()) != "[EndOfFile]")
                {
                    switch(strRead)
                    {
                        case "[PowerWord]":
                            while ((strRead = fileInput.ReadLine()) != "[/PowerWord]")
                            {
                                listPowerWord.Items.Add(strRead);
                            }
                            break;
                        case "[Action]":
                            while ((strRead = fileInput.ReadLine()) != "[/Action]")
                            {
                                listAction.Items.Add(strRead);
                            }
                            break;
                        case "[Purpose]":
                            while ((strRead = fileInput.ReadLine()) != "[/Purpose]")
                            {
                                listPurpose.Items.Add(strRead);
                            }
                            break;
                        case "[Names]":
                            while ((strRead = fileInput.ReadLine()) != "[/Names]")
                            {
                                comboIdentity.Items.Add(strRead);
                            }
                            break;
                        default:
                            break;
                    }
                }

    So: in the big picture of things, is this slower? not by much since a switch statement is pretty fast, and much faster thant if/elseif/else combinations (that would have been worse than a switch inside a for loop).  Is this code easier to maintain, change, more bug proof, and easier to debug? YES!  Should it be used to replace a simple list of assignments, where EVERY single item in the list gets unique code (like the days of the week)? OF COURSE NOT!

    For the examples given, yes, WTF definitely on days of the week.  A smarter idea would have even to put that in a predefined string table.  But there ARE situations where this is useful.
  • Charles Nadolski (unregistered) in reply to Charles Nadolski
    Anonymous:


    for(nCol = 0; nCol<ntotalcols ;="" ncol="">
    {
    </ntotalcols>
    //snip
    }



    To pre-empt any nit-picking, the forum ate half the first line and last bracket of my for loop :)
  • (cs) in reply to Charles Nadolski

    Anonymous:
    So: in the big picture of things, is this slower? not by much since a switch statement is pretty fast, and much faster thant if/elseif/else combinations (that would have been worse than a switch inside a for loop).

    I doubt that using a switch with Strings is going to be any faster than linked ifs.  Switch can be faster with int types because the compiler can build a jump table for the values.  It's more complicated with sparse values but for consecutive values the compiler can basically jump n instructions (over-simplification) when the input to the switch is n.  You can't really do that with Strings.  This is why Java doesn't allow switch with anything but int types.  I'm going to guess that C# just allows this as syntactic sugar.

    In any event the speed increase (if there is any) if likely to be negligible.  If it makes the code clearer, that's good but I hate when people obfuscate code in the name of (imaginary) 'optimization'.

  • Charles Nadolski (unregistered) in reply to dubwai
    dubwai:

    I doubt that using a switch with Strings is going to be any faster than linked ifs.  Switch can be faster with int types because the compiler can build a jump table for the values.  It's more complicated with sparse values but for consecutive values the compiler can basically jump n instructions (over-simplification) when the input to the switch is n.  You can't really do that with Strings.  This is why Java doesn't allow switch with anything but int types.  I'm going to guess that C# just allows this as syntactic sugar.

    In any event the speed increase (if there is any) if likely to be negligible.  If it makes the code clearer, that's good but I hate when people obfuscate code in the name of (imaginary) 'optimization'.



    Being new to C#, I was shocked when it allowed strings, and I agree, whatever was gained switching with int is probably lost when using strings (not knowing the exactly what the compiler does, we can't be sure though!). However, I don't think using switch obfuscates code at all.  if/elseif/else tends to make my eyes hurt.  I guess this is one of those "personal preference" things.  One of my coworkers for example prefers if/elseif/else over switches.  Whatever floats your boat I guess?

    On a side note, I've started using the ? : statement for certain if clauses after I discovered it recently.  I can definitely understand how that statement could probably drive people up the wall if used obsessively :D
  • (cs) in reply to Charles Nadolski

    Anonymous:

    Being new to C#, I was shocked when it allowed strings, and I agree, whatever was gained switching with int is probably lost when using strings (not knowing the exactly what the compiler does, we can't be sure though!).

    Unless you've got a method for creating jump tables based on Strings, I'm going stick with syntactic sugar.  I just don't think it's feasible.

    Anonymous:

    However, I don't think using switch obfuscates code at all.  if/elseif/else tends to make my eyes hurt.  I guess this is one of those "personal preference" things.  One of my coworkers for example prefers if/elseif/else over switches.  Whatever floats your boat I guess?

    On a side note, I've started using the ? : statement for certain if clauses after I discovered it recently.  I can definitely understand how that statement could probably drive people up the wall if used obsessively :D

    I wasn't suggesting that using switch was obfuscation.  I was clarifying that just because there was no optimization doesn't mean there was no value in using switch for Strings.  In other words it's generally better to make code easy to understand than try to squeeze every last bit of performance out if it.

    I really like unary if as long as it isn't abused.

  • (cs) in reply to dubwai
    dubwai:

    I wasn't suggesting that using switch was obfuscation.  I was clarifying that just because there was no optimization doesn't mean there was no value in using switch for Strings.  In other words it's generally better to make code easy to understand than try to squeeze every last bit of performance out if it.

    I really like unary if as long as it isn't abused.



    Speaking of which, I just found my first WTF looking through some code today, so I decided to submit it.  It just happens to be a unary if abuse:

    HBITMAP bmTemp = (HBITMAP)::CreateMappedBitmap(AfxGetApp()->m_hInstance, nID, IMAGE_BITMAP, &mapColor, bUseMask ? 1 : 0 );

    Notice the last parameter.
  • ChrisR (unregistered) in reply to Charles Nadolski
    Quote:
    Speaking of which, I just found my first WTF looking through some code today, so I decided to submit it.  It just happens to be a unary if abuse:

    HBITMAP bmTemp = (HBITMAP)::CreateMappedBitmap(AfxGetApp()->m_hInstance, nID, IMAGE_BITMAP, &mapColor, bUseMask ? 1 : 0 );

    Notice the last parameter.
    /Quote
    Uh, sorry guys, that's not a unary operator, that's a ternary operator.  Also, the quoted use of the ternary operator isn't really a WTF.
  • (cs) in reply to ChrisR

    <FONT size=4>

    Anonymous:
    </FONT>
    <FONT size=4>Uh, sorry guys, that's not a unary operator, that's a ternary operator.</FONT>
    <FONT size=4>
    </FONT>
    <FONT size=4>ternary, unary... it's all 'narys.  You don't have to be sorry about it.</FONT>

  • (cs) in reply to igor1960

    igor: The entire reason for this forum is to make fun of bad programmers. If you don't like it, don't visit the site. It's really that simple.

  • (cs) in reply to Rescendent
    Rescendent:

    The "case 1:break" is probablly to stop fall through, but why it isn't deleted in it entirity I guess we'll never know...


    I can't speak for the designers, but two reasons stand out: Consistency (maybe even a coding standard - that could be the real wtf!), and a default: that actually does something, but since it's not at either end I'd have to assume it's in the middle if it was there. Most likely it was at the end and new values accreted onto the end of it! xD I've seen that, and it's a huge wtf for maintainers.

    Anonymous:
    Also, the quoted use of the ternary operator isn't really a WTF.


    Since this is C++ it's equivalent to (bool)bUseMask or if the function is defined as bool, bUseMask alone. It might be a C compatible function even though it's in a class/namespace, though. It's just a silly way of writing it.

    dubwai:

    Unless you've got a method for creating jump tables based on Strings, I'm going stick with syntactic sugar.  I just don't think it's feasible.



    C# does just that, as well as modern java compilers/runtime jitters. It replaces the string constants in preprocessing with int indexes to the strings. So do other non-VB6 languages that handle strings in switches, like PHP and Perl. And while comparing your string against them to come up with the int is still hard, some compilers add a small index to speed the process considerably; I think VC 2005 does that, and maybe 2003.

    zinglons_ale:

          mov eax, 0
    for: inc eax
          inc eax
          cmp eax, 10
          jl for


    There was a second variable that was being incremented with the counter.

    zinglons_ale:

     The greatest amount of compiler psychic ability I could possibly accept is "add eax, 2" instead of two "inc eax". And even that would probably be a Bad Thing(tm).



    The pipeliner would decompile add eax,2 into two inc eax anyway, and both take as long to be pushed into the processor, so it makes no difference. (Except in shared-memory multithreading.) But if that alone is a Bad Thing, then I guess you haven't used release/optimize modes in any compiler since 1990. I'd hate to see your executables.

    I know, too long. Should have double-posted. Oh well. =p Igor's hilarious, too, like a nosy old neighbor.

  • (cs)

    <FONT face="Courier New" size=2><FONT color=#0000ff>using</FONT> System;
    <FONT color=#0000ff>using</FONT> System.Collections;
    <FONT color=#0000ff>using</FONT> System.Text;

    <FONT color=#0000ff>namespace</FONT> MoneyString
    {
        <FONT color=#008000>///

    Dummy Class to hold method</FONT>
        <FONT color=#0000ff>public</FONT> <FONT color=#0000ff>class</FONT> Money
        {
            #<FONT color=#0000ff>region</FONT> Enumerations
            <FONT color=#0000ff>enum</FONT> MoneyPower
            {
                Hundred        = 1,
                Thousand    = 2,
                Million        = 3,
                Billion        = 4,
                Trillion    = 5
            }
            <FONT color=#0000ff>enum</FONT> Ones
            {
                One        = 1,
                Two        = 2,
                Three    = 3,
                Four    = 4,
                Five    = 5,
                Six        = 6,
                Seven    = 7,
                Eight    = 8,
                Nine    = 9
            }
            <FONT color=#0000ff>enum</FONT> Tens
            {
                Ten        = 1,
                Twenty    = 2,
                Thirty    = 3,
                Forty    = 4,
                Fifty    = 5,
                Sixty    = 6,
                Seventy    = 7,
                Eighty    = 8,
                Ninenty    = 9
            }
            <FONT color=#0000ff>enum</FONT> TensSpecial
            {
                Eleven        = 1,
                Twelve        = 2,
                Thirteen    = 3,
                Fourteen    = 4,
                Fithteen    = 5,
                Sixteen        = 6,
                Seventeen    = 7,
                Eightteen    = 8,
                Nineteen    = 9
            }
            #<FONT color=#0000ff>endregion</FONT>
            #<FONT color=#0000ff>region</FONT> Methods
    <FONT color=#008000>        ///
            /// Transforms a number into an English(Word) Readable Money Value.
            ///

            /// <PARAM name="money">A number.</PARAM>
            /// <RETURNS>English Word Money String.</RETURNS></FONT>
            <FONT color=#0000ff>public</FONT> <FONT color=#0000ff>static</FONT> <FONT color=#0000ff>string</FONT> ToString(<FONT color=#0000ff>int</FONT> money)
            {
                #<FONT color=#0000ff>region</FONT> var
                StringBuilder sb = new StringBuilder();
                <FONT color=#0000ff>string</FONT>[] mon = money.ToString("C").Split(',');
                <FONT color=#0000ff>string</FONT> ret = "Ammount can not exceed $999,999,999,999,999.00";
                <FONT color=#0000ff>string</FONT> sCache = "";
                <FONT color=#0000ff>int</FONT> iCache = 0;
                <FONT color=#0000ff>bool</FONT> skip = false;
                #<FONT color=#0000ff>endregion</FONT>
                #<FONT color=#0000ff>region</FONT> Return if Number is to Large
                <FONT color=#0000ff>if</FONT>(mon.Length > 5) <FONT color=#0000ff>return</FONT> ret; <FONT color=#008000>//more than 5 is alot of money</FONT>
                #<FONT color=#0000ff>endregion</FONT>
                #<FONT color=#0000ff>region</FONT> clean string
                mon[0] = mon[0].Replace("$",""); //remove dollar sign
                mon[mon.Length - 1] = mon[mon.Length - 1].Split('.')[0]; <FONT color=#008000>//trim of the decimal places</FONT>
                #<FONT color=#0000ff>endregion</FONT>
                #<FONT color=#0000ff>region</FONT> Loopy Money Switch
                <FONT color=#0000ff>for</FONT>(<FONT color=#0000ff>int</FONT> i = 0; i < mon.Length; i++)
                {
                    <FONT color=#0000ff>for</FONT>(<FONT color=#0000ff>int</FONT> j = 0; j < mon[i].Length; j++)
                    {
                        <FONT color=#0000ff>switch</FONT>(mon[i].Length)
                        {
                            <FONT color=#0000ff>case</FONT> 1:
                                #<FONT color=#0000ff>region</FONT> Ones
                                sCache = mon[i].Substring(j, 1);
                                iCache = int.Parse(sCache);
                                <FONT color=#0000ff>if</FONT>(iCache > 0)
                                {
                                    sCache = ((Ones)iCache).ToString();
                                    sb.Append(sCache);
                                }
                                sb.Append(" ");
                                <FONT color=#0000ff>break</FONT>;
                                #endregion
                            <FONT color=#0000ff>case</FONT> 2:
                                #<FONT color=#0000ff>region</FONT> Place Switch
                                <FONT color=#0000ff>switch</FONT>(j)
                                {
                                    <FONT color=#0000ff>case</FONT> 0:
                                        #<FONT color=#0000ff>region</FONT> Tens
                                        sCache = mon[i].Substring(j, 1);
                                        iCache = int.Parse(sCache);
                                        <FONT color=#0000ff>if</FONT>(iCache > 0)
                                        {
                                            <FONT color=#0000ff>if</FONT>(iCache == 1)
                                            {
                                                sCache = mon[i].Substring(j + 1, 1);
                                                iCache = int.Parse(sCache);
                                                sCache = ((TensSpecial)iCache).ToString();
                                                sb.Append(sCache);
                                                skip = <FONT color=#0000ff>true</FONT>;
                                            }
                                            <FONT color=#0000ff>else</FONT>
                                            {
                                                sCache = ((Tens)iCache).ToString();
                                                sb.Append(sCache);
                                            }
                                        }
                                        sb.Append(" ");
                                        <FONT color=#0000ff>break</FONT>;
                                        #<FONT color=#0000ff>endregion</FONT>
                                    <FONT color=#0000ff>case</FONT> 1:
                                        #<FONT color=#0000ff>region</FONT> Ones
                                        <FONT color=#0000ff>if</FONT>(!skip)
                                        {
                                            sCache = mon[i].Substring(j, 1);
                                            iCache = int.Parse(sCache);
                                            <FONT color=#0000ff>if</FONT>(iCache > 0)
                                            {
                                                sCache = ((Ones)iCache).ToString();
                                                sb.Append(sCache);
                                            }
                                            sb.Append(" ");
                                        }
                                        skip = <FONT color=#0000ff>false</FONT>;
                                        break;
                                        #<FONT color=#0000ff>endregion</FONT>
                                }
                                #<FONT color=#0000ff>endregion</FONT>
                                break;
                            <FONT color=#0000ff>case</FONT> 3:
                                #<FONT color=#0000ff>region</FONT> Place Swich
                                <FONT color=#0000ff>switch</FONT>(j)
                                {
                                    <FONT color=#0000ff>case</FONT> 0:
                                        #<FONT color=#0000ff>region</FONT> Hundreds
                                        sCache = mon[i].Substring(j, 1);
                                        iCache = int.Parse(sCache);
                                        <FONT color=#0000ff>if</FONT>(iCache > 0)
                                        {
                                            sCache = ((Ones)iCache).ToString();
                                            sb.Append(sCache);
                                            sb.Append(" ");
                                        }
                                        sb.Append(" ");
                                        <FONT color=#0000ff>break</FONT>;
                                        #endregion
                                    <FONT color=#0000ff>case</FONT> 1:
                                        #<FONT color=#0000ff>region</FONT> Tens
                                        sCache = mon[i].Substring(j, 1);
                                        iCache = int.Parse(sCache);
                                        <FONT color=#0000ff>if</FONT>(iCache > 0)
                                        {
                                            <FONT color=#0000ff>if</FONT>(iCache == 1)
                                            {
                                                sCache = mon[i].Substring(j + 1, 1);
                                                iCache = int.Parse(sCache);
                                                sCache = ((TensSpecial)iCache).ToString();
                                                sb.Append(sCache);
                                                skip = <FONT color=#0000ff>true</FONT>;
                                            }
                                            <FONT color=#0000ff>else</FONT>
                                            {
                                                sCache = ((Tens)iCache).ToString();
                                                sb.Append(sCache);
                                                skip = <FONT color=#0000ff>false</FONT>;
                                            }
                                        }
                                        sb.Append(" ");
                                        <FONT color=#0000ff>break</FONT>;
                                        #endregion
                                    <FONT color=#0000ff>case</FONT> 2:
                                        #<FONT color=#0000ff>region</FONT> Ones
                                        sCache = mon[i].Substring(j, 1);
                                        iCache = int.Parse(sCache);
                                        <FONT color=#0000ff>if</FONT>(iCache > 0)
                                        {
                                            <FONT color=#0000ff>if</FONT>(!skip)
                                            {
                                                <FONT color=#0000ff>if</FONT>(mon[i].Substring(1, 1) != "0")
                                                {
                                                    sb.Remove(sb.Length - 1, 1);
                                                    sb.Append("-");
                                                }
                                                sCache = ((Ones)iCache).ToString();
                                                sb.Append(sCache);
                                            }
                                        }
                                        skip = <FONT color=#0000ff>false</FONT>;
                                        sb.Append(" ");
                                        <FONT color=#0000ff>break</FONT>;
                                        #<FONT color=#0000ff>endregion</FONT>
                                }
                                #<FONT color=#0000ff>endregion</FONT>
                                <FONT color=#0000ff>break</FONT>;
                        }
                        #<FONT color=#0000ff>region</FONT> Add Hundred..?
                        <FONT color=#0000ff>if</FONT>(mon[i].Length == 3 && j == 0 && mon[i].Substring(j, 1) != "0")
                        {
                            sb.Append("Hundred");
                            sb.Append(" ");
                        }
                        #<FONT color=#0000ff>endregion</FONT>
                    }
                    #<FONT color=#0000ff>region</FONT> Add Power..?
                    <FONT color=#0000ff>if</FONT>(i != (mon.Length - 1))
                    {
                        sCache = ((MoneyPower)mon.Length - i).ToString();
                        sb.Append(sCache);
                        sb.Append(" ");
                    }
                    #<FONT color=#0000ff>endregion</FONT>
                }
                #<FONT color=#0000ff>endregion</FONT>
                #<FONT color=#0000ff>region</FONT> Get, Append Dollars, and Return English Money String
                ret = sb.ToString();
                ret += "Dollars";
                <FONT color=#0000ff>return</FONT> ret;
                #<FONT color=#0000ff>endregion</FONT>
            }
            #<FONT color=#0000ff>endregion</FONT>
        }
    }</FONT>

    I had wanted to say something, but now after having to <FONT color=#ff0000 size=6>HTML FORMAT MY CODE I FORGOT, WTF</FONT>. Can we like turn the lame @$$ WYSIG HTML Editor Spoof off so I can use my BBCode tags...? You know

    WTF
    [php]WTF[/php][vbcode]WTF[/vbcode]:cool: I mean if we are posting code let's make it easy not hard... wtf am I just stupid..? I mean the other forums I use let me turn that funk off....... I can pick like plain text, lite editor, and full wysig htm crap iframe document.open(iframe.document).write('wtf');

  • (cs) in reply to x-sol

    Um, quick question.  Why didn't you just use string.Format("$%.2f", dSomeFloatingPointUSDollars), since it looks like you're using C#?

  • (cs) in reply to foxyshadis
    foxyshadis:

    dubwai:

    Unless you've got a method for creating jump tables based on Strings, I'm going stick with syntactic sugar.  I just don't think it's feasible.



    C# does just that, as well as modern java compilers/runtime jitters. It replaces the string constants in preprocessing with int indexes to the strings. So do other non-VB6 languages that handle strings in switches, like PHP and Perl. And while comparing your string against them to come up with the int is still hard, some compilers add a small index to speed the process considerably; I think VC 2005 does that, and maybe 2003.

    Java doesn't allow switching on Strings so I'm not sure what you mean when you say Java compilers do this.  There are going to be more Strings than integer values in most languages.  I still don't see how you can create a jump table.  If you are talking about a hashtable, well, that's something else entirely.

Leave a comment on “Switched on Loops”

Log In or post as a guest

Replying to comment #:

« Return to Article