• DOA (unregistered)

    nice, very nice

  • BradC (cs)

    Heh. I've written an XML "parser" like that. Well, not each character in succession, but just looking for the "magic" value in the middle.

    Nice WFT'ery!!!

  • wow (unregistered)

    beautiful!

  • Sid2K7 (unregistered)

    I just died a little inside.

    Very inspired work, Keith, VERY inspired.

    captcha: craaazy - indeed!

  • MX5Ringer (cs)

    Hey that's not fair!! I had a proper comment in my post and everything :((

    Ok, Ok, Perhaps I shouldn't have replied to the stroppy post, I should have just started a new one.

    Anyway,

    Nice WTF! Personally I prefer #02 tho, I'm still chuckling about it now. (Would have liked it even more if the cached results were slower to find than the uncached ones tho)

    Thanks

  • JokerPokerUberSmoker (unregistered)

    The best I've seen so far

  • PAG (unregistered)

    I really like the idea of a contest to use a overly complicated solution to a simple problem.

    I know everybody can badly code, but only a handful of person can do this effectively...

  • PSWorx (cs)

    I also like the XML format he used. Like W3CSchools already so wisely stated, "we should always keep web services generic"...

  • FDF (unregistered)

    Some people have just too much free time.

  • Someone (unregistered)
    Alex:
    The value it’s from XML comes from server_send_value():

    Which calculator did you use to help you write this sentence?

  • Random832 (cs)

    TRWTF is, XML is case-sensitive anyway, so he didn't need all those extra ORs.

  • Frost Cat (unregistered)
    /* compare two strings */
    int string_equals( const char *s1, const char *s2 ) {
       int sum1 = 0;
       int sum2 = 0;
    
       do { sum1 += *s1; } while( *( ++s1 ) );
       do { sum2 += *s2; } while( *( ++s2 ) );
    
       return sum1 == sum2;
    }

    Wow,that's impressive. "16" == "61" and probably "34" and "2221" as well.

  • klucas (cs) in reply to Frost Cat

    It's close enough to strcmp(), and it works correctly in the place that I use it.

  • SomeCoder (unregistered) in reply to FDF
    FDF:
    Some people have just too much free time.

    I was thinking the exact same thing.

  • AdT (unregistered)
    Comment held for moderation.
  • Chris (unregistered) in reply to Frost Cat

    "16" == "61" == "34" != "2221"

    There's a huge DC offset on the ASCII values that kicks in as soon as you've got extra characters.

  • Coincoin (cs) in reply to Frost Cat

    This solution is still better than...

    s1.GetHash() == s2.GetHash()

    ...because you will quickly notice the sum compare is failing and will promptly fix it. If you compare hashes, the bug will be so uncommon nobody will ever take the time to debug and fix it and people will just blame it on cosmic rays.

  • diaphanein (unregistered) in reply to Frost Cat
    Frost Cat:
    /* compare two strings */
    int string_equals( const char *s1, const char *s2 ) {
       int sum1 = 0;
       int sum2 = 0;
    

    do { sum1 += *s1; } while( *( ++s1 ) ); do { sum2 += *s2; } while( *( ++s2 ) );

    return sum1 == sum2; }

    Wow,that's impressive. "16" == "61" and probably "34" and "2221" as well.

    Another nugget: If either of the strings is empty, you'll either segfault, or read a whole lotta garbage.

  • T P (unregistered)

    I like how editing the "cache" allows you to define your own math.

    For example, I changed test.txt in C:\5.0000-ADD-5.0000 to be 3.14159

  • T P (unregistered)

    Of course, my personal WTF for the day is commenting on #03 instead of #02.

  • Ancient_Hacker (cs)

    This is pretty bad. I didnt submit mine, as I got sick working on it. The idea was to write out two files of lengths x and y, execute "type x+y >z; dir /b z", then extract the file length sum from the directory listing. It worked, for small values of "worked".

  • Me (unregistered) in reply to Someone
    Someone:
    Alex:
    The value it’s from XML comes from server_send_value():

    Which calculator did you use to help you write this sentence?

    I believe "extracted" was extracted.

  • Josh (unregistered)
    Comment held for moderation.
  • MikeCD (unregistered)

    I'm a big fan of the my_malloc() implementation, especially as I've seen it in the wild :-/

  • ailivac (cs)

    This is definitely my favorite out of the four posted so far, and I think it will be hard for any of the eight to come to top this. The unnecessarily complicated "distributed" design was good, but its frequent re-creation of basic library routines made it even better.

    For the XML part, this looks like a great example of someone who completely missed the point of XML and uses it just for the sake of being able to say their program uses XML. The advantage of using XML comes when you need to store or exchange a large data structure, since XML generators and parsers are available for almost any platform you might need. If you write your own parser and generator, it looks mostly stupid, but if might still be worth it if you're storing a lot of information in it or sending it to another program. But when you have exactly one piece of important information in the whole document, then it's 100% WTFery.

    I also liked the custom C<string_length> (I know BBCode isn't POD, but i can pretend) function. It seems to work by grabbing 4-byte chunks of the string and shifting them around to check for 0 bytes in the different positions (although I might have something wrong, since it looks like it would only work if C had short-circuit logical and, which I didn't think it did). It's just the kind of code one of those "premature optimization" people would write after hearing that reading memory at the full alignment boundary is much faster than doing it one byte at a time. (processors have had cache memory for how many decades now?)

  • klucas (cs) in reply to MikeCD
    MikeCD:
    I'm a big fan of the my_malloc() implementation, especially as I've seen it in the wild :-/

    Whoa, I haven't seen it in the wild. I based it off something that I found at work that was like this:

    void *my_malloc(size_t size) {
       void *ptr = NULL;
       
       ptr = malloc(size);
       if (ptr == NULL) {
          ptr = malloc(size);
          if (ptr == NULL) {
             exit(-1);
          }
       }
    }
    

    Ironically, g_malloc() does not return NULL unless size is 0. If g_malloc() fails, the program exits.

  • klucas (cs) in reply to ailivac
    ailivac:
    This is definitely my favorite out of the four posted so far, and I think it will be hard for any of the eight to come to top this. The unnecessarily complicated "distributed" design was good, but its frequent re-creation of basic library routines made it even better.

    For the XML part, this looks like a great example of someone who completely missed the point of XML and uses it just for the sake of being able to say their program uses XML. The advantage of using XML comes when you need to store or exchange a large data structure, since XML generators and parsers are available for almost any platform you might need. If you write your own parser and generator, it looks mostly stupid, but if might still be worth it if you're storing a lot of information in it or sending it to another program. But when you have exactly one piece of important information in the whole document, then it's 100% WTFery.

    I also liked the custom C<string_length> (I know BBCode isn't POD, but i can pretend) function. It seems to work by grabbing 4-byte chunks of the string and shifting them around to check for 0 bytes in the different positions (although I might have something wrong, since it looks like it would only work if C had short-circuit logical and, which I didn't think it did). It's just the kind of code one of those "premature optimization" people would write after hearing that reading memory at the full alignment boundary is much faster than doing it one byte at a time. (processors have had cache memory for how many decades now?)

    C does have short-circuited AND; that's how it works.

  • Roy (unregistered)
    Submitter #03:
    There are whole host of other gems in util.h, including:
    * my_malloc() - malloc with error recovery (by calling itself again on failure)</div></BLOCKQUOTE>
    

    What, you mean, like in sysvinit's source code?

    /*
     *  Non-failing allocation routines (init cannot fail).
     */
    void *imalloc(size_t size)
    { 
      void  *m;
      
      while ((m = malloc(size)) == NULL) {
        initlog(L_VB, "out of memory");
        do_sleep(5);
      }
      memset(m, 0, size);
      return m;
    }
  • topcat_arg (cs)

    i having a lot of fun today reading this.. although there were a lot of time since I read C++ code...

    anyway: I think that this comment (/* case insensitive */) should be taken out, it's makes code clear! (unless it's case insensitive..)

  • BradC (cs) in reply to Ancient_Hacker
    Ancient_Hacker:
    This *is* pretty bad. I didnt submit mine, as I got sick working on it. The idea was to write out two files of lengths x and y, execute "type x+y >z; dir /b z", then extract the file length sum from the directory listing. It worked, for small values of "worked".
    My new favorite phrase.
  • Taejo (cs) in reply to MX5Ringer
    MX5Ringer:
    Nice WTF! Personally I prefer #02 tho, I'm still chuckling about it now. (Would have liked it even more if the cached results were slower to find than the uncached ones tho)

    My calculator's cache is slower than working stuff out (for addition and subtraction; my multiplication and division are extremely slow). Database access requires constructing the query string (in XML Lisp) using strcat (O(L^2) where L = len(query)), parsing that (my parser does recreate XML's tree structure, but it requires that tags be surrounded by spaces), executing the parse tree (with each variable reference in O(V) for V variables in the environment) and then O(N) to find the item in the cache (it's a linked list).

    Of course, this is all done even if the item isn't in the cache: so that's even slower. But in many cases, cache access time dominates.

  • H3SO5 (cs)

    I LOVE IT! This will become my main calculator.

  • rjnewton (cs)

    So how does one distinguish between a divide-by-zero error and a legitimate answer to 1867964280 * 2?

  • klucas (cs) in reply to rjnewton
    rjnewton:
    So how does one distinguish between a divide-by-zero error and a legitimate answer to 1867964280 * 2?

    It's stored as a double not an int. A double is 64 bits, and an int is 32 bits. I set the first 32 bits of the double to be 0xdeadbeef, then treat it as a double. The result is random because the second 32 bits are uninitialized.

    I run this:

    main() {
       union {double d; unsigned int i;} u;
       u.i = 0xdeadbeef;
       printf("%g\n", u.d);
    }
    

    And I get a different result every time.

  • mh (unregistered) in reply to klucas
    klucas:
    MikeCD:
    I'm a big fan of the my_malloc() implementation, especially as I've seen it in the wild :-/

    Whoa, I haven't seen it in the wild. I based it off something that I found at work that was like this:

    void *my_malloc(size_t size) {
       void *ptr = NULL;
       
       ptr = malloc(size);
       if (ptr == NULL) {
          ptr = malloc(size);
          if (ptr == NULL) {
             exit(-1);
          }
       }
    }
    

    Ironically, g_malloc() does not return NULL unless size is 0. If g_malloc() fails, the program exits.

    I bloody well WROTE something similar in production code once! It went something like:

    • search for a free slot in a linked list
    • if found return it, otherwise...
    • add a new empty list member to the start
    • call recursively

    Perfectly viable code when used properly, but obviously a WTF when it's copied without understanding. ;D

  • Mark McConnell (unregistered)

    bc rules, and you are elite for it. though, you didn't notice the 'ibase' and 'obase' variables inside bc, apparently.. making you slightly less elite.

  • chrismcb (cs) in reply to mh
    mh:
    I bloody well WROTE something similar in production code once! It went something like:
    • search for a free slot in a linked list
    • if found return it, otherwise...
    • add a new empty list member to the start
    • call recursively

    Perfectly viable code when used properly, but obviously a WTF when it's copied without understanding. ;D

    You CREATED the NODE then ADDED it to the start... WHY do you need to make a recursive call?

  • Mad Merlin (unregistered)

    It looks like the the code isn't 64-bit clean either, it just segfaults whenever you try to push a second button. That problem doesn't crop up when compiled as 32-bit code though.

  • klucas (cs) in reply to Mad Merlin
    Mad Merlin:
    It looks like the the code isn't 64-bit clean either, it just segfaults whenever you try to push a second button. That problem doesn't crop up when compiled as 32-bit code though.
    That's a feature. It doesn't work on bigendian either.
  • ELIZA (unregistered) in reply to chrismcb
    chrismcb:
    mh:
    I bloody well WROTE something similar in production code once! It went something like:
    • search for a free slot in a linked list
    • if found return it, otherwise...
    • add a new empty list member to the start
    • call recursively

    Perfectly viable code when used properly, but obviously a WTF when it's copied without understanding. ;D

    You CREATED the NODE then ADDED it to the start... WHY do you need to make a recursive call?

    Chris, think this through. As I understand it, the code reads:

    1. If there is a free node then 1i) Return it
    2. Add node
    3. Call steps 1 through 3

    If I were writing it, I would write it as:

    1. If there is a free node then 1i) Return it
    2. Add node Either 3A) Call step 1i Or 3B) Return it Depending on how complicated the return code. In fact, I would more likely write:
    3. If there is no free node then 1i) add node
    4. Return it (in more formal pseudocode, it would be: To_Return = FindFreeNodeAndReturnPointerOrReturnNULL(list) If To_Return == NULL Then AddNodeAndReturnPointer(list) Return To_Return ) Although I could imagine someone writing a whilst-loop for the task: While To_Return == NULL To_Return = pointer of first free node found To_Return = pointer of added free node End Loop Return To_Return

    PS If a function returns a pointer, is it still called the return value?

  • 855 (unregistered)
    Comment held for moderation.

Leave a comment on “OMGWTF Finalist #03: The estimator”

Log In or post as a guest

Replying to comment #:

« Return to Article