• AuMatar (unregistered) in reply to coppro
    coppro:
    The char name[] syntax is C and C++, and precisely equal to char * name, just slighly more confusing.

    No it isn't.

    char name[]; name = NULL;

    Result: syntax error

    char *name; name = NULL;

    Result: success

    Think of an array as like a reference. Yes, under the hood its a pointer, but the address it points to can't be changed and can't be null. Just like a reference to a value.

  • SatanClaus (unregistered)

    Did you know you can only next if-else statements 256 deep in visual studio? I know and it isn't because of some fact I ran across in the manual.

  • (cs) in reply to lol
    lol:
    camelCase

    NotCamelCase

    Yeah, dats PascalCase not camelCase! Alternatively, Win32Case.

  • Buffled (unregistered) in reply to xtremezone
    xtremezone:
    Jack Hughes:
    the char[] NineCharstring statement is C++ specific... unless recent C standards have back ported it from C++
    Funny, I've never seen that syntax in C++...
    Therefore we all know that it does not exist? Thanks for clearing that up.
  • (cs) in reply to my name
    my name:
    printf ("%.9d\n",1);
    Ah, but is that call really Fred-safe?
  • Buddy (unregistered) in reply to Erasmus Darwin
    Erasmus Darwin:
    Pim:
    Does this say that Bruce wrote a routine that did the same thing as Fred's routine? Why?

    Fred's routine would render -10 as "000000-10" instead of "-00000010". Bruce kept that behavior just in case other code was dependent on it.

    I'm guessing something like:

    void ConvertLongToString(char NinecharString[], long Number)
    {
        int length;
        char temporary[20];
    
        /* Get length of formatted number */
        length = snprintf(temporary, 20, "%ld", Number);
    
        /* Reformat Fred style - note extra NULLs just in case */
        snprintf(NinecharString, 9 + 1, "%s%s", "000000000\0\0\0\0\0\0\0\0\0\0" + length, temporary);
    }
    

    This won't overwrite the buffer but it's still has a huge problem, in particular for large magnitudes, losing the least significant digits will effectively divide by ten, one hundred, one thousand, etc.

  • (cs) in reply to Dudehole
    Dudehole:
    lol:
    camelCase

    NotCamelCase

    Yeah, dats PascalCase not camelCase! Alternatively, Win32Case.
    The real camel case.

  • Mark V Shaney (unregistered) in reply to pjt33
    pjt33:
    Compilers which don't emit errors when two function names longer than 32 characters clash are an additional WTF.

    People that post even when they don't know the difference between a compiler and a linker are another WTF too...

  • (cs) in reply to kastein

    Knowing Bruce, I should point out here that this used to be known as "Spaceship Code" for precisely that reason!

  • (cs) in reply to Perfect coder
    Perfect coder:
    And why would passing a zero to the function yield nulls? There's a "<= 0" test right there...

    What if you passed 1000000001? It wouldn't trip any of the if cases so you hit the end of the function without modifying NinecharString: I'm assuming this is a story-telling bug...

  • Duke of New York (unregistered) in reply to pjt33
    pjt33:
    Compilers which don't emit errors when two function names longer than 32 characters clash are an additional WTF.
    The real WTF is that people replying to this comment are picking on the distinction between a compiler and a linker, and ignoring that it would be impossible to print such errors. I'll leave it as an exercise to figure out why.
  • (cs) in reply to Fast Eddie
    Fast Eddie:
    Pim:
    I'm worried about this line in the article.
    Not daring to do the sensible, one-line sprintf()-based solution, Bruce instead wrote a replacement that behaved exactly the same way.
    Does this say that Bruce wrote a routine that did the same thing as Fred's routine? Why?
    It is obvious... ...Bruce has now become a 'consultant' and is paid by the line.
    Actually it's more that Bruce wrote a number of 'variants' of this, and it was deemed that they should go with the one that introduced the least change in the output.

    The file went from this system into another, and for "whatever" reason, the other system (which was not written by the company Bruce works for BTW) accepted the output of the existing program (except the nulls, which was the bug causing the problem in the first place).

    In fact, if he had written it differently, it's quite possible that the back-end would also need to be re-written - at the customers expense.

    PS: The file format used was also produced by another device, and the file format the code produced had to match that to a tee. The previous device sent data over a serial cable at slow speed, so you can see why the format was chosen, as the customer wanted to re-use the existing back-end. That's why the fields are all fixed length, there are no delimiters, etc.

  • Giorgos Keramidas (unregistered)

    The way some 0 Number); instances are missing a comma, that would separate 0 from Number and match the number of formatting directives, is actually cute.

    Apparently someone actually typed each instance manually, so CopyAndPasteProgramming was not used. Really cool! :)

  • Intellivision (unregistered)

    This code makes me think of The Dreadnaught Factor

  • (cs)
    00000000I
    0000can't
    00believe
    000nobody
    00000made
    00000this
    00obvious
    00000joke
    000000yet
  • Pax (unregistered) in reply to bjolling
    bjolling:
    Month number, sales tax percentage, weight in pounds, you name in.
    My name in what? Come on, the suspense is killing me!

    Edit: I get it! My name in a nine char string!

    Activating pedant mode: The counterpoint of "you name in" is "I name in", not "my name in" (that's the counterpoint of "your name in").

  • Pax (unregistered) in reply to coppro
    coppro:
    The char name[] syntax is C and C++, and precisely equal to char * name, just slighly more confusing.

    It is not precisely equal, try using sizeof on these babies:

    char x[10];
    char *y = malloc(10);
    
  • Pax (unregistered) in reply to Mark V Shaney
    Mark V Shaney:
    pjt33:
    Compilers which don't emit errors when two function names longer than 32 characters clash are an additional WTF.

    People that post even when they don't know the difference between a compiler and a linker are another WTF too...

    I suspect most people that use IDEs don't know the difference between compilers and linkers. These new-fangled tools will never catch on :-)

  • scruffy (unregistered) in reply to Duke of New York
    Duke of New York:
    pjt33:
    Compilers which don't emit errors when two function names longer than 32 characters clash are an additional WTF.
    The real WTF is that people replying to this comment are picking on the distinction between a compiler and a linker, and ignoring that it would be impossible to print such errors. I'll leave it as an exercise to figure out why.

    Well the linke could certainly detect the collisions because there would be multiple symbol definitions with the same 32 char name. It could then just emit an error such as "multiple definitions of symbol %s", with a list of the object files containing such definitions, and (what the hell) line numbers harvested from the debug data.

    The real WTF was the comment that Bruce's code "worked the same way", I hope this doesn't mean that bruce produced an if-else ladder too. I can think of two alternatives to embed minus signs in the numbers ... void ConvertLongToString(char NinecharString[], long Number) { int c,w; char * zeros="00000000"; c=(Number<0); /(Number<0)?1:0;/ for(w=Number;w;w/=10)c++; if(c<10) snprintf(NinecharString,9,"%s%ld",zeros+c,Number); else snprintf(NinecharString,zeros); /*safer than it looks;-) */ }

    Or void ConvertLongToString(char NinecharString[], long Number) { int c; c=snprintf(NinecharString,9,"%ld",Number); if((c<0)||(c>9)) { sprintf(NinecharString,"000000000"); } else if(c) { memmove(NinecharSring+c,NinecharString,9-c); while(c--)NinecharString[c]='0'; } } Depending on your aversion to division or function calls.

    If you have an aversion to pointer arithmetic you shouldn't be coding C.. oh hang on, Fred was still trying to believe in Strings, he shouldn't be coding in C anyway.

  • scruffy (unregistered)

    Actually I meant else if (c!=9) WTF insomnia

  • (cs) in reply to Buffled
    Buffled:
    xtremezone:
    Jack Hughes:
    the char[] NineCharstring statement is C++ specific... unless recent C standards have back ported it from C++
    Funny, I've never seen that syntax in C++...
    Therefore we all know that it does not exist? Thanks for clearing that up.
    I never said that. Do provide a reference, please.
  • scruffy (unregistered) in reply to scruffy
    scruffy:
    Actually I meant else if (c!=9) WTF insomnia
    And c=(Number<=0); too come to think of it (coping with the space for - and the special case of non-zero characters used to store a zero value.
  • (cs) in reply to Pax

    Interesting code.

    Does anyone get paid by the line these days? I thought that sort of practice had long since been retired.

  • Captain Oblivious (unregistered) in reply to Captain Oblivious
    Captain Oblivious:
    Let's see... the <= from 0 onward should be < instead. There also seem to be some missing commas near the end. I won't try to find the other bugs, unless I actually want to get a headache.

    Who the fuck are you.

  • (cs) in reply to Captain Oblivious
    Captain Oblivious:
    Captain Oblivious:
    Let's see... the <= from 0 onward should be < instead. There also seem to be some missing commas near the end. I won't try to find the other bugs, unless I actually want to get a headache.
    Who the fuck are you.
    So register your user name and quit complaining
  • (cs) in reply to Captain Oblivious

    If you want to know where code like this comes from, and why it's still being done today, look no further than the asp.net forums:

    http://forums.asp.net/t/1416271.aspx

  • (cs)

    The grossest bug is that, if you give it a value over one billion, it doesn't put anything at all into NinecharString. Hey, we get an ASCII text file with an embedded core dump! Neat! Hard on the reader, though.

  • Andre (unregistered)

    My 50ct:

    sprintf(NinecharString, "%09ld", Number); if (Number < 0 && Number > -10000000) // Move minus { int i; for (i = 1; i < 9; i++) if (NinecharString[i] != '0') break; NinecharString[0] = '0'; NinecharString[i - 1] = '-'; }

  • Bibble (unregistered) in reply to SatanClaus
    SatanClaus:
    Did you know you can only next if-else statements 256 deep in visual studio? I know and it isn't because of some fact I ran across in the manual.

    I knew that. It's really annoying, but there are workarounds...

  • YanmanSucks (unregistered) in reply to Yanman

    The true WTF is you don't know WTF you are talking about. It's not php, it's C RTFA

  • WPower60 (unregistered)

    This joke was shit

  • myname (unregistered)

    I think this article was written by a Springsteen fan... "Bruce" got a call from "the Boss" ? :)

  • cynical western educated code smith (unregistered) in reply to Mr B
    Mr B:
    If you want to know where code like this comes from, and why it's still being done today, look no further than the asp.net forums:

    http://forums.asp.net/t/1416271.aspx

    Wow butchering c# and English at the same time, that's the efficiency you can only get from a "large, cheap, well educated work force"

  • NK (unregistered)

    Does it work in a multi-freded-environment?

    Ha, ha.

  • (cs) in reply to Mr B
    Mr B:
    If you want to know where code like this comes from, and why it's still being done today, look no further than the asp.net forums:

    http://forums.asp.net/t/1416271.aspx

    Groan... the level of expertise in there...

    "its great to work in .net platform and if else is a very useful tool provided by it."

    So they never encountered any other platform that provided if else. Geez. And those people build websites! Oh man. But the biggest WTF is the entry by the fool who tries to educate them, at the end. What a waste of breath that is.

  • scruffy (unregistered) in reply to Pim
    Pim:
    Groan... the level of expertise in there...

    "its great to work in .net platform and if else is a very useful tool provided by it."

    So they never encountered any other platform that provided if else. Geez. And those people build websites! Oh man. But the biggest WTF is the entry by the fool who tries to educate them, at the end. What a waste of breath that is.

    To be fair I think the last guy was a troll who was just showing off some of c#'s features.... over and above the earth shattering "if else" feature. Someone had already suggested using an array of strings lookup. I'd love to see those guys CVs though. "I has five year of c-hash experiences."

  • Duke of New York (unregistered) in reply to scruffy
    scruffy:
    Duke of New York:
    pjt33:
    Compilers which don't emit errors when two function names longer than 32 characters clash are an additional WTF.
    The real WTF is that people replying to this comment are picking on the distinction between a compiler and a linker, and ignoring that it would be impossible to print such errors. I'll leave it as an exercise to figure out why.

    Well the linke could certainly detect the collisions because there would be multiple symbol definitions with the same 32 char name. It could then just emit an error such as "multiple definitions of symbol %s"

    sigh .. no.

    When a compiler/linker suite has an identifier name limit, it can't recognize collisions because it's not storing the entire identifier name.

  • JoLoCo (unregistered) in reply to Yanman
    I tried to troll, but then I realised I was speaking the truth.
    I see!
  • The Wanderer (unregistered) in reply to Pax
    Pax:
    I suspect most people that use IDEs don't know the difference between compilers and linkers. These new-fangled tools will never catch on :-)
    That's nothing.

    I once had an extended argument with someone who insisted that he wrote his C code in a compiler.

    Nothing I said could convince him otherwise.

  • The Wanderer (unregistered) in reply to Duke of New York
    Duke of New York:
    *sigh* .. no.

    When a compiler/linker suite has an identifier name limit, it can't recognize collisions because it's not storing the entire identifier name.

    So?

    It could still produce an error along the lines of "redefinition of existing symbol 'foo' at file2.c line 1234 (previous definition: file1.c line 123)", and leave it up to the programmer to figure out what the actual identifier names are beyond the 32 characters which got printed.

    If there's some reason why that wouldn't work, I'd be interested to hear it.

  • Duke of New York (unregistered) in reply to The Wanderer
    The Wanderer:
    If there's some reason why that wouldn't work, I'd be interested to hear it.
    Because the program's not storing the entire identifier name. Think it through.
  • (cs) in reply to The Wanderer
    The Wanderer:
    Pax:
    I suspect most people that use IDEs don't know the difference between compilers and linkers. These new-fangled tools will never catch on :-)
    That's nothing.

    I once had an extended argument with someone who insisted that he wrote his C code in a compiler.

    Nothing I said could convince him otherwise.

    Was he working in a language that compiled to C as an intermediary language?

  • The Wanderer (unregistered) in reply to Duke of New York
    Duke of New York:
    The Wanderer:
    If there's some reason why that wouldn't work, I'd be interested to hear it.
    Because the program's not storing the entire identifier name. Think it through.
    ...maybe I'm missing something.

    The program isn't storing the entire identifier name, no.

    It's storing the first 32 characters.

    The behaviour I'm expecting/describing is roughly (semi-pseudocode):

    while ( new_symbol = truncate_to_32( scan_for_symbol_definition() ) {
        if(new_symbol is in list_of_known_symbols) {
            error(DUPLICATE_SYMBOL);
            exit;
        } else {
            add_to_known_list(new_symbol);
        }
    }
    

    In other words: when the program sees a symbol being defined, it should be able to compare that against its list of "known defined symbols", and if - as here - 32-character string is already in its list, say "hey! we have a collision!" and take appropriate action.

    Just because it can't tell that the beyond-32-characters part makes it not a collision doesn't mean it can't detect a collision within those first 32 characters...

    If there's more to it than that which would provide another pitfall, you'll need to be more specific, because I'm not seeing it.

  • The Wanderer (unregistered) in reply to Captain Oblivious
    Captain Oblivious:
    The Wanderer:
    I once had an extended argument with someone who insisted that he wrote his C code in a compiler.

    Nothing I said could convince him otherwise.

    Was he working in a language that compiled to C as an intermediary language?

    Nope - he was working in C.

    Plus, IIRC he was talking about opening up his source file in a compiler to edit it...

  • Duke of New York (unregistered) in reply to The Wanderer

    I guess I misunderstood the suggestion. Carry on.

    The Wanderer:
    Nope - he was working in C.

    Plus, IIRC he was talking about opening up his source file in a compiler to edit it...

    Perfect example of taking the platform for granted. ("Whoa, so you're saying that the compiler is a program too?")

  • (cs) in reply to Pim
    Pim:
    Mr B:
    If you want to know where code like this comes from, and why it's still being done today, look no further than the asp.net forums:

    http://forums.asp.net/t/1416271.aspx

    Groan... the level of expertise in there...

    "its great to work in .net platform and if else is a very useful tool provided by it."

    So they never encountered any other platform that provided if else. Geez. And those people build websites! Oh man. But the biggest WTF is the entry by the fool who tries to educate them, at the end. What a waste of breath that is.

    One has to try.

    :)

  • Scruffy (unregistered) in reply to The Wanderer
    The Wanderer:
    Duke of New York:
    The Wanderer:
    If there's some reason why that wouldn't work, I'd be interested to hear it.
    Because the program's not storing the entire identifier name. Think it through.
    ...maybe I'm missing something.

    The program isn't storing the entire identifier name, no.

    It's storing the first 32 characters.

    Just because it can't tell that the beyond-32-characters part makes it not a collision doesn't mean it can't detect a collision within those first 32 characters...

    If there's more to it than that which would provide another pitfall, you'll need to be more specific, because I'm not seeing it.

    Exactly, if two symbols longer than 32 chars collide, then the abbreviated forms will also collide.

    UNLESS You mean that as each symbol is read from an object file it's full name is looked up in the symbol table being generated, and then it's truncated before being stored... In which case the linker's own code is a WTF, quite clearly because of it's own internal inconsistency. Some object file format or code generator that consistently truncates symbol names however does not make collision detection impossible.

    I've come across the "Truncation causes collision" issue a number of times, but I've never had any trouble coding to detect it!

  • DaveC (unregistered) in reply to xtremezone

    gcc will not take char[] as a type in either C or C++. It's perfectly good Java though :-)

  • usitas (unregistered) in reply to savar
    savar:
    00000000I
    0000can't
    00believe
    000nobody
    00000made
    00000this
    00obvious
    00000joke
    000000yet
    0000000We
    00000have
    standards
  • Pink (unregistered) in reply to David Emery
    David Emery:
    >ConvertLongToString(char NinecharString[], long Number)

    The posting makes fun of the long names. Would it be better if this were called "cls" or "cls9"?

    Certainly there's a lot better way to write the code. But I thought the comment on long function names to be a cheap shot. Having done some maintenance programming pouring through listings, seeing a meaningful identifier is a blessing, rather than having to go external to the routine I'm studying to figure out what 'cls9" does.

    Surely ConvertLongInToString(char NinecharString[], long Number) is more expressive.

    or clits(char NinecharString[], long Number) if that's just too long for you.

Leave a comment on “Fred Code”

Log In or post as a guest

Replying to comment #:

« Return to Article