• (cs) in reply to Faxmachinen
    Faxmachinen:
    acne:
    Another one: how do you swap the values of 2 int variables without using a third variable?
    asm("xchgl %%eax,%%ebx" : "=a"(a), "=b"(b) : "a"(a), "b"(b) :);

    The advantage over swap(a, b); is that a and b don't have to be of the same type. Although, in the wrong hands that would probably be a disadvantage.

    Though the disadvantage is that, if I understand the GCC ASM syntax correctly (which is far from guaranteed), it constrains the compiler's optimization opportunities by forcing a and b to be in eax and ebx at that instruction.

    It's also definitely not portable between compilers or architectures.

  • Omg like oh my Goddess (unregistered) in reply to Bill
    Bill:
    Amazing that after 5 (FIVE) pages of commentary, people are still missing the basic logic of the initial post and posting flawed code. I have to agree with others here: the real WTF is all the folks posting on here that look down their noses at some poor, out-of-context example and then return to their jobs where they most likely write code just as flawed as what they post here.

    that is why USA need so many greencards... too many noobs and yet proud

  • Jon (unregistered) in reply to acne
    acne:
    Benanov:
    acne:
    Hint : max(a,b) = (a + b + abs(a - b)) /2 and min(a,b) = (a + b - abs(a - b)) / 2

    I have never seen that before, but that is a beautiful piece of mathematics. I have never thought about it before, but it makes sense.

    What's the bigger of two numbers? Find the midpoint between the two numbers, and then add half the distance.

    Subtracting half the distance yields the minimum.

    Kudos to you for sharing that with me!

    You're welcome!

    I saw such constructs in algorithm class. My teacher was quite fond of 'alternative' ways of doing things.

    Another one: how do you swap the values of 2 int variables without using a third variable?

    a = a + b
    b = a - b
    a = a - b
  • Jon (unregistered) in reply to acne
    acne:
    Another one: how do you swap the values of 2 int variables without using a third variable?
    Some languages can do this painlessly, with "(psetq a b b a)" or "a, b = b, a".
  • flatline (unregistered)

    This could have been done by a person who thinks in assembler and possibly has a mind corrupted by microoptimization. Translated, he's doing something like:

    cmp eax, 0 jeq exit cmp eax, 1 jeq exit cmp eax, 2 jeq exit cmp eax, 3 jeq exit mov eax, 0 exit: ret

    A reasonably smart compiler will translate the original C code into something very much like this. For example, If this were (for some weird reason) a performance critical path, the default case (number not one of 0,1,2,3) won't go through any jumps.

  • k0werd (unregistered) in reply to Omg like oh my Goddess

    Hey I just tested:

    $Bill = (!smart) ? true : false;

    and it returned true!

  • Bill (unregistered) in reply to k0werd
    k0werd:
    Hey I just tested:

    $Bill = (!smart) ? true : false;

    and it returned true!

    Of course, since my eyes tend to miss "the obscured '!' operator" late in the day, I'm cool with that code.

  • jon (unregistered)

    Ooo. Numerics. We should use FORTRAN here, because of the numberes:

      SUBROUTINE GETMSG(SELECT)
      IMPLICIT REAL (A-H,O-Z)
      COMMON /MSGS/ MSG, IND, CHOICE
      COMPLEX*16 MSG
      DIMENSION MSG(43)
      LOGICAL CHOICE
      EQUIVALENCE (IND, INDEX)
      INTEGER*4 SELECT
      GO TO (100,200,300,400) SELECT
    

    100 CONTINUE INDEX = 0 GO TO 500 200 CONTINUE INDEX = 1 GO TO 500 300 CONTINUE INDEX = 2 GO TO 500 400 CONTINUE INDEX = 3 GO TO 500 C comment: goto 500 500 CONTINUE RETURN END

    Captcha: smile (at this)

  • Security Dude (unregistered)

    From a security perspective, he might have done the right thing in that his code does constrain the output to a defined set.

  • Faxmachinen (unregistered) in reply to EvanED
    EvanED:
    Though the disadvantage is that, if I understand the GCC ASM syntax correctly (which is far from guaranteed), it constrains the compiler's optimization opportunities by forcing a and b to be in eax and ebx at that instruction.
    Good point. I tend to use specific registers for testing, because it makes them easier to distinguish. For production code you'd want to let the compiler pick the registers:
    asm("xchgl %0,%1" : "=r"(a), "=r"(b) : "0"(a), "1"(b) :);
    EvanED:
    It's also definitely not portable between compilers or architectures.
    Indeed.
  • RichNFamous (unregistered)

    I have it on good authority that this bit of code is from the original source code behind the amazing Big Red Button:

    http://www.pixelscapes.com/spatulacity/button.htm

  • Måns (unregistered)

    Posix sh. The language that outperforms Java.

    function ml {
    	 if [ $1 -lt 4 -a $1 -gt 0 ] ; 
                then echo "$1"
    	    else echo "0"
    	 fi 
    }
    
  • mariush (unregistered)

    Private Function GetValue(selected as Long) as Long GetValue = iif(selected>3,0,iif(selected<0,0,selected)) End Function

  • (cs) in reply to mariush

    This is the shortest "swap 2 variables" implementation I was able to come up with.

    b^=a^=b,a^=b;

    I tested it by gcc -W -Wall -Wextra compiles just fine. (gcc 4.1.2)

  • ?? (unregistered) in reply to Anontoo

    You just broke the application by introducing an integer underflow.

  • Looce (unregistered)
    private int GetMessage(int selected)
    {
      return selected >= 0 && selected <= 3 ? selected : 0;
    }

    Of course, the point of this thread is to post the shortest, and the most convoluted, code, so here I go:

    ; Returns the message corresponding to the selected element.
    ; in:  EAX - the selected element's index.
    ; out: EAX - the message corresponding to the specified element.
    ; FLAGS destroyed. Other registers unchanged. No stack usage.
    GetMessage PROC FAR
      cmp   eax, 0
      js    ret0   ; go return 0, the number is negative
      cmp   eax, 3
      jg    ret0   ; go return 0, the number is > 3
      ; fall through if the number is between 0 and 3 incl.
      retf
    ret0:
      xor   eax, eax
      retf
    GetMessage ENDP

    Or how about a Java version:

    private static int GetMessage(int sel)
    {
      // Get the number of elements above this element:
      int elementsAbove = 1;
      while (--sel != 0) ++elementsAbove;
    
      while (sel != elementsAbove) {
        if (elementsAbove & 3 == (int) Math.PI - 3 && elementsAbove & ~3 == 0)
          return elementsAbove & 3;
        if (elementsAbove & 3 == (int) Math.PI - 2 && elementsAbove & ~3 == 0)
          return elementsAbove & 3;
        if (elementsAbove & 3 == (int) Math.PI - 1 && elementsAbove & ~3 == 0)
          return elementsAbove & 3;
        if (elementsAbove & 3 == (int) Math.PI && elementsAbove & ~3 == 0)
          return elementsAbove & 3;
      }
    
      return (sel + elementsAbove - (int) Math.PI) << 8 + (int) (Math.random() * Integer.MAX_VALUE) + new java.util.HashMap().size();
    }
  • Jon (unregistered)

    #define GetMessage(X) (X & 3)

  • Omg like oh my Goddess (unregistered) in reply to Jon
    Jon:
    #define GetMessage(X) (X & 3)

    you are also enginieueieur from India or just cannot code?

  • jub (unregistered) in reply to Meh
    Meh:
    private int GetMessage( int selected )

    { while((selected<=3)&&(selected>=1)) { return selected; }

      return 0;
    

    }

    Why not?

    Why not use a return as the only statement in a while loop? Because you really wanted to use an IF, that's why.

  • jub (unregistered) in reply to Meh
    Meh:
    private int GetMessage( int selected )

    { while((selected<=3)&&(selected>=1)) { return selected; }

      return 0;
    

    }

    Why not?

    Why not use a return as the only statement in a while loop? Because you really wanted to use an IF, that's why.

  • Jon (unregistered) in reply to Omg like oh my Goddess
    Omg like oh my Goddess:
    Jon:
    #define GetMessage(X) (X & 3)

    you are also enginieueieur from India or just cannot code?

    "also"? How are things in India, anyway?

    Short, sweet, same result as original. Anybody can obfuscate.

  • Anonymous coward (unregistered) in reply to Mike G
    1. Having MORE lines of code for a function does NOTE make it slower

    Depends on your compiler, and your platform (longer code might not fit into the caches).

    1. Having MORE lines of code for a function does NOTmake it compile any slower

    Wrong. More lines of code means that the compiler will need to do more disk I/O, parsing, etc.

    1. Having explicit variables instead of implicit temporaries does not make a function run any slower.

    Depends on your compiler.

    1. There is NO TAX on lines of code, be as explicit as you dare, and then be a little more explicit. The easier you can make your code to understand for others, the better a programmer you are.

    Sort of. If you're programming resource constrained embedded systems (like I am), code size and speed do matter, sometimes (a lot) more than clarity.

  • Omg like oh my Goddess (unregistered) in reply to Jon
    Jon:
    Omg like oh my Goddess:
    Jon:
    #define GetMessage(X) (X & 3)

    you are also enginieueieur from India or just cannot code?

    "also"? How are things in India, anyway?

    Short, sweet, same result as original. Anybody can obfuscate.

    you better go to check C for dummies

  • Viridium (unregistered)

    // <param name="selected">a value between 0 and 3 inclusive</param> private int GetMessage(int sequence) { return sequence; }

  • Jon (unregistered) in reply to Omg like oh my Goddess
    Omg like oh my Goddess:
    Jon:
    Omg like oh my Goddess:
    Jon:
    #define GetMessage(X) (X & 3)

    you are also enginieueieur from India or just cannot code?

    "also"? How are things in India, anyway?

    Short, sweet, same result as original. Anybody can obfuscate.

    you better go to check C for dummies

    sigh ok, I'll byte...WTF are you talking about?? Here's code and output. Macro updated to handle full range of input, staying bitwise for fun

    #define GetMessage(X) ((X&0xfffffffc)?0:X&3) main() { int i; for(i=-5; i <= 5; i++) printf("GetMessage(%d)==%d\n", i, GetMessage(i)); }

    produces

    GetMessage(-5)==0 GetMessage(-4)==0 GetMessage(-3)==0 GetMessage(-2)==0 GetMessage(-1)==0 GetMessage(0)==0 GetMessage(1)==1 GetMessage(2)==2 GetMessage(3)==3 GetMessage(4)==0 GetMessage(5)==0

    OMFG! It's correct!

  • Omg like oh my Goddess (unregistered) in reply to Jon

    finally. in meantime until you realized it, India pwned you. And I am forgiving you the fact that you are casting constant to int without knowing its size.

  • (cs) in reply to Jon
    Jon:
    Omg like oh my Goddess:
    Jon:
    Omg like oh my Goddess:
    Jon:
    #define GetMessage(X) (X & 3)

    you are also enginieueieur from India or just cannot code?

    "also"? How are things in India, anyway?

    Short, sweet, same result as original. Anybody can obfuscate.

    you better go to check C for dummies

    sigh ok, I'll byte...WTF are you talking about??

    He's talking about the original code (which IS quoted in the post you replied to...), #define GetMessage(x) (x&3), which maps most numbers outside of the range 0-3 to non-zero numbers and hence is wrong.

    You'll notice the code you give below is DIFFERENT than the code being commented on in the post you're replying to, and which was written by you...

    Here's code and output. Macro updated to handle full range of input,

    Oh, see, you DO realize why the person was continuing to insist you were wrong.

    staying bitwise for fun

    #define GetMessage(X) ((X&0xfffffffc)?0:X&3) main() { int i; for(i=-5; i <= 5; i++) printf("GetMessage(%d)==%d\n", i, GetMessage(i)); }

    produces

    GetMessage(-5)==0 GetMessage(-4)==0 GetMessage(-3)==0 GetMessage(-2)==0 GetMessage(-1)==0 GetMessage(0)==0 GetMessage(1)==1 GetMessage(2)==2 GetMessage(3)==3 GetMessage(4)==0 GetMessage(5)==0

    OMFG! It's correct!

    Really?

    14. ~$ cat delete.c
    #define GetMessageMacro(X) ((X&0xfffffffc)?0:X&3)
    
    int GetMessageFunction(int X) {
      return ((X&0xfffffffc)?0:X&3);
    }
    
    main() {
      printf("GetMessageMacro(1|0)   ==%d\n", GetMessageMacro(1|0));
      printf("GetMessageFunction(1|0)==%d\n", GetMessageFunction(1|0));
    }
    15. ~$ gcc delete.c
    16. ~$ ./a.out
    GetMessageMacro(1|0)   ==0
    GetMessageFunction(1|0)==1
    

    OMFG! Your macro behaves differently than a function that does the "same' thing!

    You know, if you're going to act all smug about your C-l33tness, and say that it's just as valid to use macros as a function, you should at least check and make sure you realize the pitfalls of macros first and try to avoid them.

  • Rob Baillie (unregistered)

    I'm constantly amazed at how many people will read this blog, feeling very superior, and then post code that doesn't work.

    Wow

  • Omg like oh my Goddess (unregistered) in reply to Rob Baillie
    Rob Baillie:
    I'm constantly amazed at how many people will read this blog, feeling very superior, and then post code that doesn't work.

    Wow

    indeed

  • Jon (unregistered) in reply to EvanED
    EvanED:
    Jon:
    Omg like oh my Goddess:
    Jon:
    Omg like oh my Goddess:
    Jon:
    #define GetMessage(X) (X & 3)

    you are also enginieueieur from India or just cannot code?

    "also"? How are things in India, anyway?

    Short, sweet, same result as original. Anybody can obfuscate.

    you better go to check C for dummies

    sigh ok, I'll byte...WTF are you talking about??

    He's talking about the original code (which IS quoted in the post you replied to...), #define GetMessage(x) (x&3), which maps most numbers outside of the range 0-3 to non-zero numbers and hence is wrong.

    You'll notice the code you give below is DIFFERENT than the code being commented on in the post you're replying to, and which was written by you...

    Here's code and output. Macro updated to handle full range of input,

    Oh, see, you DO realize why the person was continuing to insist you were wrong.

    staying bitwise for fun

    #define GetMessage(X) ((X&0xfffffffc)?0:X&3) main() { int i; for(i=-5; i <= 5; i++) printf("GetMessage(%d)==%d\n", i, GetMessage(i)); }

    produces

    GetMessage(-5)==0 GetMessage(-4)==0 GetMessage(-3)==0 GetMessage(-2)==0 GetMessage(-1)==0 GetMessage(0)==0 GetMessage(1)==1 GetMessage(2)==2 GetMessage(3)==3 GetMessage(4)==0 GetMessage(5)==0

    OMFG! It's correct!

    Really?

    14. ~$ cat delete.c
    #define GetMessageMacro(X) ((X&0xfffffffc)?0:X&3)
    
    int GetMessageFunction(int X) {
      return ((X&0xfffffffc)?0:X&3);
    }
    
    main() {
      printf("GetMessageMacro(1|0)   ==%d\n", GetMessageMacro(1|0));
      printf("GetMessageFunction(1|0)==%d\n", GetMessageFunction(1|0));
    }
    15. ~$ gcc delete.c
    16. ~$ ./a.out
    GetMessageMacro(1|0)   ==0
    GetMessageFunction(1|0)==1
    

    OMFG! Your macro behaves differently than a function that does the "same' thing!

    You know, if you're going to act all smug about your C-l33tness, and say that it's just as valid to use macros as a function, you should at least check and make sure you realize the pitfalls of macros first and try to avoid them.

    Okay, sorry about the tone. Was more indigestion at "enginieueieur" than anything.

    You make a good point. I guess I've developed a few blinders from being a one-man shop. I'm the only one that uses my code, and I do know the difference between macros and functions.

    Though a few more parens (now it's looking ugly) fix your example, I thought you'd point out the more obvious problem - GetMessage(i++).

    You were right. I was wrong.

  • Anonymous (unregistered)

    I still haven't seen any Postscript here. So, here it goes: :D

    /GetMessage {
        dup 0 eq {
    	pop 0
        } {
    	dup 1 eq {
    	    pop 1
    	} {
    	    dup 2 eq {
    		pop 2
    	    } {
    		dup 3 eq {
    		    pop 3
    		} {
    		    pop 0
    		} ifelse
    	    } ifelse
    	} ifelse
        } ifelse
    } bind def
    
  • RANDY ROZ (unregistered)

    Haskell again (but correct this time):

    f x | 0 <= x && x <= 3 = x f _ = 0

  • darwin (unregistered)

    OK, enough fun with rewriting it in the most bizarre manner possible. Seriously, now, with this function being so easy to understand and rewrite into a sensible form, doesn't anyone think it's a pretty big WTF that the consultant's response was "We have to rewrite everything?"

    Admittedly, this code may just be the tip of an iceberg, and some of the other problems may be harder to fix that this little gem, but rewriting is far too often the first thing people think of, and rarely the right answer.

    Right now I'm working on a major update to some software that has been around for about 5 or 6 years. It has WTFs in it that would blind you or send you fleeing, screaming for mercy. It also has years of domain knowledge baked into it. If we tried to just rewrite it from scratch (as several of the developers have suggested), it would probably take another 5-6 years, at which point it would probably be as messed up as the code we've already got.

  • darwin (unregistered) in reply to EvanED
    bleh:
    int firstPower; firstPower = 11;

    No, no, The First Power was a movie with Lou Diamond Phillips. But more to the point, why do you write it that way instead of just:

    int firstPower = 11;

    Or is that just part of the whole "paid by the line" theme of this post?

    My favorite so far is the Ruby one-liner someone posted.

  • boonmirror (unregistered)

    certainly, with all the high IQ's here, an AI language is needed: prolog

    GetMessage(0,0). GetMessage(4,_) := fail. GetMessage(X,X) := X>0, GetMessage(X-1,X-1). GetMessage(X,0).

    hope i remember right... last time i used prolog was 16 years ago.

  • (cs)

    I don't know. We don't really know the context in which this code was written. I don't think this guy is an idiot. I think he has a sense of humor. I haven't read through all of the comments, so maybe I'm not the first to say this but, I think this is just a stub function. At some point he would have fleshed it out to do something useful. At this point in the project it was probalby accpetable for it to just return its parameter. He just decided to come with a creative way of doing it. Anyway, just my 2 cents.

  • European (unregistered) in reply to Optimizer
    Optimizer:
    Here's another variant, for flavor.

    private int GetMessage( int selected ) { static const int ONE = 1; int index = 0;

    // Get the Message
    switch( selected )
    {
        case 0: index += ONE;
        case 1: index += ONE;
        case 2: index += ONE;
        case 3: index += ONE;
    }
    
    return index;
    

    }

    You mean:

    switch( selected )
    {
        case 3: index += ONE;
        case 2: index += ONE;
        case 1: index += ONE;
    }
    
  • Underpaid (unregistered) in reply to Bryan
    Bryan:
    private int GetMessage( int selected ) { return ((selected < 0 || selected > 3) ? 0 : selected); }

    private int GetMessage(int s) {return (s & ~3)?0:s;}

    Saved some chars on the paycheck.

  • lolwut (unregistered)

    private int GetMessage( int selected ){ return selected 3< ? null : selected; }

  • mh (unregistered)

    Am I late for this party? Never mind, read it and weep:

    #pragma warning (disable: 4715)
    int GetMessage (int selected)
    {
    	int i;
    	int j;
    	int x;
    	char strmsg[64];
    
    	sprintf (strmsg, "%60i", *((unsigned *) &selected));
    
    	for (i = 0; ; i++)
    	{
    		if (strmsg[i + 1] == 0)
    		{
    			j = (((1 << (strmsg[i] - 0x30)) & 0x0f) * (0xff + 0x01)) >> 9;
    
    			for (x = 0; ; x++)
    			{
    				if (!j) return x;
    				j /= 2;
    			}
    		}
    
    		for (j = 0x01; j < 0xff; j++) if (!!((strmsg[i] - 0x20) & j)) return 0;
    	}
    }
    #pragma warning (default: 4715)
  • DaveJ (unregistered)

    You people need to learn proper exception handling.

    #include <excpt.h>

    int GetMessage( int selected ) { __try { if ((selected & 0xFFFFFFFC) != 0) { int q = 42; q /= (q-q); } return selected; } __except ( EXCEPTION_EXECUTE_HANDLER ) { return 0; } }

    That is the safest and most efficient way of doing this.

Leave a comment on “Paid by the Line”

Log In or post as a guest

Replying to comment #:

« Return to Article