• Steve (unregistered) in reply to Paul Carpenter
    Paul Carpenter:
    #define false 1 #define true 0
    The source for the game Power Sports Soccer had something similar, along with

    #define BEGIN { #define END } #define FOR for #define IF if #define THEN { #define ELSE } else { #define ENDIF }

    There was an include file with about 30 more nuggets like that in it...

    Ah, yes, the hallmark of a beginning C programmer who has just discovered macros.

    By the way, in the original K&R book, there's even a brief discussion of this:

    The C Programming Language:
    Since the imlementation of #define is a macro prepass, not part of the compiler proper, there are very few grammatical restrictions on what can be defined. For example, Algol fans can say

    #define then
    #define begin {
    #define end ;}
    and then write
    if ( i > 0 ) then
    
    begin
        a = 1;
        b = 2
    end</b></pre></div></BLOCKQUOTE>Thus spake K&R and endeth the lesson.
    

    I seem to recall that elsewhere they counsel against the practice however I can't find it

  • (cs) in reply to Anonymous
    Christophe Beugnet:
    #define false 1 #define true 0
    Little did Christophe know, he was developing with April Fool's C.
  • Kehvarl (unregistered) in reply to Fiona
    Fiona:
    HUUUUUUUUURF

    It's a hippopotomus! It's not my cow!!

  • Zap Brannigan (unregistered) in reply to Thief^
    Thief^:
    andem:
    if((0 == DblSpread) || (0 == DblSpread))

    This comparison order is actually an old trick to avoid unintentional assignment in if() clause from the days when IDEs/compilers didn't warn about those. Constant = Variable assignment resulted in compiler error and saved some debugging time.

    That's not the wtf, the wtf is that it's exactly the same comparison twice.
    I also make all of my comparisons twice. It's the only way to be really really sure.

  • SomeCoder (unregistered)

    Let me just say that I love C/C++ but it lets you get WAY too carried away with defines. When you can say #define false 1... that's trouble.

  • Harrow (unregistered) in reply to Steve
    Steve:
    Regarding the final item, a number of years ago I had a discussion over a few Tsing Taos with some VMS weenies (er, hackers) about the proper values for true and false. Their contention was that since in VMS a return value of zero indicates success and any other value returned indicates failure of a function or operation, it makes sense that 1 (or any nonzero value) should be interpreted as false and only 0 be interpreted as true.

    They considered the C language's use of 0 as a false value to be a significant wart on the language.

    I can say that after many Tsing Taos and several servings of Kung Pao Death I was inclined to agree.

    I worked at DEC for years. I argued that the meaning of the argument returned from a VMS SVC function should answer the question "Did it fail?" and therefore zero is false and any nonzero is true. But VMS weenies were an alien breed, from a strange planet where mental effort is regarded as evil.

    -Harrow.

  • RealLanguage (unregistered) in reply to Niels
    Niels:
        lSend = IIf(lSend = True, True, False)
    Obviously because there are other values than True and False. (FileNotFound etc.)

    In a real language I'd just have done lSend = !!lSend; for it, concise way to force a value to boolean.

    I hope you're joking... in a language worth anything, you wouldn't have to do this in the first place. It's called "strong static typing".

  • RealLanguage (unregistered) in reply to Steve
    Steve:
    Regarding the final item, a number of years ago I had a discussion over a few Tsing Taos with some VMS weenies (er, hackers) about the proper values for true and false. Their contention was that since in VMS a return value of zero indicates success and any other value returned indicates failure of a function or operation, it makes sense that 1 (or any nonzero value) should be interpreted as false and only 0 be interpreted as true.

    They considered the C language's use of 0 as a false value to be a significant wart on the language.

    I can say that after many Tsing Taos and several servings of Kung Pao Death I was inclined to agree.

    The real WTF is that you think an integer should be interpreted as a boolean...

  • (cs)

    I don't know about you guys, but I'm looking forward to a post made by Top Cod3r.

  • RealLanguage (unregistered) in reply to Satanicpuppy
    Satanicpuppy:
    Some of the conditional stuff I can see; you write it, you change it, you write it, you change it, you write it and FINALLY the data matches what it's supposed to and you don't recheck.
    Ah, the good old "coding by accident".

    W3C are currently working on version 2.0 which will include a true source of randomness, parallel universes and a doomsday machine.

  • SeanJA (unregistered)

    twentyspaces is obviously a spacer (haha). When the need for more space between x and y, well... just add to twentyspaces instead of changing the variable names to match throughout the code, not really a wtf, more like laziness.

    On the other hand... never ever name your variables that way...

  • (cs) in reply to blah

    The word "comparison" is being cleaned and restored. "Comparison" had become faded and dingy after decades of exposure to air pollution and sunlight. The word was moved outdoors for the 1926 World Fair in Wembley, England and had been unprotected from the elements since then.

    "Comparison" will be returned to the English language in April 2009. In the interim, the word "comparisment" is available as an alternative.

  • darkmage0707077 (unregistered) in reply to RealLanguage
    RealLanguage:
    Satanicpuppy:
    Some of the conditional stuff I can see; you write it, you change it, you write it, you change it, you write it and FINALLY the data matches what it's supposed to and you don't recheck.
    Ah, the good old "coding by accident".

    W3C are currently working on version 2.0 which will include a true source of randomness, parallel universes and a doomsday machine.

    Ah, cool! They're about to release a demo:

    http://en.wikipedia.org/wiki/Lhc

  • Max (unregistered)

    Don't forget the usefulness of a non-integer base for your mathematics... After all, I know ALL the digits of Pi.

    ... in base Pi.

  • #define true false (unregistered) in reply to snoofle
    snoofle:
    alex:
    #define false 1
    #define true 0 
    Brought to you by the same folks who came up with FileNotFound?
    Definitely not. FileNotFound was a later enhancement by another developer.
  • Someone You Don't Know (unregistered) in reply to Someone You Know
    Someone You Know:
    WhiskeyJack:
    Ah, someone beat me to it. Comparisment is a word now?
    And a perfectly cromulent one at that.
    That's brillig... err, I mean, brillant!
  • sf (unregistered) in reply to Andy Goth
    Andy Goth:
    alex:
    #define false 1
    #define true 0
    #define ZERO -1
    Remember that? I took a second look at the code, and it turns out I was wrong. Here's how it actually reads:
    #define NEGATIVE_ONE 0
    In my opinion, the following would be much more straightforward and clear:
    #define ZERO true - false
    #define NEGATIVE_ONE true * false
    
  • Steve (unregistered) in reply to RealLanguage
    RealLanguage:
    The real WTF is that you think an integer should be interpreted as a boolean...
    I don't. C does. And when in C, I do as C does.

    Okay?

  • Dan (unregistered) in reply to Hope that helps
    Hope that helps:
    WhiskeyJack:
    Ah, someone beat me to it. Comparisment is a word now?
    http://www.comparisment.com/ is a registered domain, so the word must be in some dictionary somewhere!

    No, that doesn't follow. It just means more than one person made up a word. URL's do not have the same validity as a dictionary. If you were being sarcastanstic, I'm sorry that it missed me.

  • (cs) in reply to sf
    sf:
    In my opinion, the following would be much more straightforward and clear:
    #define ZERO true - false
    #define NEGATIVE_ONE true * false
    int x = NEGATIVE_ONE * ZERO;
    int y = ZERO * NEGATIVE_ONE;
    printf("%d %d\n", x, y);
    will print -1 0. :^)
  • Richard (unregistered)
    if (connected || !connected) { //ED: Snip }

    It also depends on the language. Many 4GL type languages designed for database work consider 'null' to be valid and treat it just as SQL does - so that could just be a really stupid way of saying:

    if (connected is not null) { // whatever }

    But yeah, its probably just stupid.

    TRWTF on the twentyspaces one (as well as COMMA for that matter) is people using variable (or constant) names that describe their initial state rather than their purpose. In these cases, FIELD_SEPARATOR would have made a lot more sense.

  • (cs) in reply to Andy Goth
    Andy Goth:
    sf:
    In my opinion, the following would be much more straightforward and clear:
    #define ZERO true - false
    #define NEGATIVE_ONE true * false
    int x = NEGATIVE_ONE * ZERO;
    int y = ZERO * NEGATIVE_ONE;
    printf("%d %d\n", x, y);
    will print -1 0. :^)
    It's not how big it is...
  • Roney (unregistered) in reply to Zap Brannigan
    Zap Brannigan:
    Thief^:
    andem:
    if((0 == DblSpread) || (0 == DblSpread))

    This comparison order is actually an old trick to avoid unintentional assignment in if() clause from the days when IDEs/compilers didn't warn about those. Constant = Variable assignment resulted in compiler error and saved some debugging time.

    That's not the wtf, the wtf is that it's exactly the same comparison twice.
    I also make all of my comparisons twice. It's the only way to be really really sure.

    I nuke my comparisons from orbit.

  • (cs) in reply to Andy Goth
    Andy Goth:
    Stephen Bayer:
    I was under the impression that bases needed to be whole numbers over 1.
    A number base (a.k.a. radix) does not need to be a whole number; that just makes it easier to work with. The Unix DC program (or at least the dc.sed version) supports fractional input and output radixes, via the 'i' and 'o' commands. Type 12.5;i;20;p; (replacing ; with newlines), and it'll print 25. Take the input number 20, expand it to 2*(12.5**1)+0*(12.5**0), and you get 25. If dc has a fractional output base, it's forced to spell out each "digit" as a decimal number, separating the "digits" with spaces. For example, 3.4;o;20;p; yields 1 1.6 3.0, since 1*(3.4**2)+1.6*(3.4**1)+3*(3.4**0) = 20.
    hmmm...

    arcanine:~ joemck$ dc 12.5 i 20 p 24

    arcanine:~ joemck$ dc 3.4 o 20 p 202

    BTW, this is in Mac OS X Leopard (based on BSD)

  • foo (unregistered) in reply to RealLanguage
    RealLanguage:
    Steve:
    Regarding the final item, a number of years ago I had a discussion over a few Tsing Taos with some VMS weenies (er, hackers) about the proper values for true and false. Their contention was that since in VMS a return value of zero indicates success and any other value returned indicates failure of a function or operation, it makes sense that 1 (or any nonzero value) should be interpreted as false and only 0 be interpreted as true.

    They considered the C language's use of 0 as a false value to be a significant wart on the language.

    I can say that after many Tsing Taos and several servings of Kung Pao Death I was inclined to agree.

    The real WTF is that you think an integer should be interpreted as a boolean...

    That doesn't even come close to Perl, which has "0 but true" which is 0 when used as a number but true when used as a boolean. That's a WTF built into the language.

  • lokey (unregistered) in reply to Zap Brannigan
    Zap Brannigan:
    Thief^:
    andem:
    if((0 == DblSpread) || (0 == DblSpread))

    This comparison order is actually an old trick to avoid unintentional assignment in if() clause from the days when IDEs/compilers didn't warn about those. Constant = Variable assignment resulted in compiler error and saved some debugging time.

    That's not the wtf, the wtf is that it's exactly the same comparison twice.
    I also make all of my comparisons twice. It's the only way to be really really sure.

    HI SANTA!

  • (cs) in reply to Harrow
    Harrow:
    Steve:
    Regarding the final item, a number of years ago I had a discussion over a few Tsing Taos with some VMS weenies (er, hackers) about the proper values for true and false. Their contention was that since in VMS a return value of zero indicates success and any other value returned indicates failure of a function or operation, it makes sense that 1 (or any nonzero value) should be interpreted as false and only 0 be interpreted as true.

    They considered the C language's use of 0 as a false value to be a significant wart on the language.

    I can say that after many Tsing Taos and several servings of Kung Pao Death I was inclined to agree.

    I worked at DEC for years. I argued that the meaning of the argument returned from a VMS SVC function should answer the question "Did it fail?" and therefore zero is false and any nonzero is true. But VMS weenies were an alien breed, from a strange planet where mental effort is regarded as evil.

    -Harrow.

    Well, it's all quite interesting and historical, really.

    Language-wise, the "original" values for true and false were -- in BCPL, at least, and we're talking procedural rather than symbolic languages like LISP here -- 0 and -1, respectively. I suppose that only really makes sense with twos complement, and it depends upon whether you consider the rest state "true" or "false." But Martin Richards didn't half bang on about it. Me, I'd have chosen 0xdead and 0xbeef, thus leaving plenty of room for FileNotFound variants; but there you go. Why K&R chose to invert their legacy, I just don't know.

    OS-wise, I suppose it's down to your preferred variant of Multics descendant. Unix is, obviously, C, and thus true/false is pretty much a given. VMS (and possibly WinNT, by extension) is in a bit of a murky middle ground. Stratus VOS got round the whole thing by being PL/1 based, and not allowing return values from OS calls at all -- which made interoperability between languages a joy.

    I don't recall any problems arising from my writing multi-process debugging scripts in C for a COBOL application (yes, it could be done, and trivially), but then there's probably a bankrupt supermarket chain somewhere in Idaho that would disagree with me.

  • Shill (unregistered) in reply to Kehvarl
    Kehvarl:
    Fiona:
    HUUUUUUUUURF

    It's a hippopotomus! It's not my cow!!

    Excellent reference, I declare you the winner. You may collect your prize at the door.

  • Dennis C. (unregistered)

    #define false 1 #define true 0

    Which is fine as long as the code you write refers to the two constants. Too much code however does not refer to them and just assumes that "true" equals 1.

  • Mog (unregistered) in reply to Dennis C.
    Dennis C.:
    #define false 1 #define true 0

    Which is fine as long as the code you write refers to the two constants. Too much code however does not refer to them and just assumes that "true" equals 1.

    Wow. Just as I thought comments on this site couldn't be more of a WTF. I really hope I did just miss your sarcasm.

  • (cs) in reply to Mog

    I don't know about you guys, but I can't wait for T0pCod3r to produce for us a production ready masterpiece consisting of selections from the above codez.

    holds breath

  • James (unregistered) in reply to Stephen Bayer
    I was under the impression that bases needed to be whole numbers over 1.. ie. base 2, base 3, base 4, base 5, ... ok.. this could go on for a while.. i think there are a lot more whole numbers over 1. I used to use random bases when doing my fourth grade math homework, then argue with the teacher about the validity of my answers, calling her an idiot for not agreeing with me that 8 + 5 = 11

    Nah, you're not having real fun with math until you're doing all your work in base e.

  • James (unregistered) in reply to Zap Brannigan
    Zap Brannigan:
    Thief^:
    andem:
    if((0 == DblSpread) || (0 == DblSpread))

    This comparison order is actually an old trick to avoid unintentional assignment in if() clause from the days when IDEs/compilers didn't warn about those. Constant = Variable assignment resulted in compiler error and saved some debugging time.

    That's not the wtf, the wtf is that it's exactly the same comparison twice.
    I also make all of my comparisons twice. It's the only way to be really really sure.

    What if there's a boolean tracking variable in the implementation of ==? Then you really need to make all your comparisons at least 3 times to be sure. I mean, why take chances?

  • (cs)

    Well, obviously:

    class SomeClass
    {
    private int ActualDblSpread = -2;
    public int DblSpread
    {
    get
    {
    ++ActualDblSpread;
    if(ActualDblSpread < 0) return 0;
    return ActualDblSpread;
    }
    }
    public void SomeMethod()
    {
    if((0 == DblSpread) || (0 == DblSpread))
      SwapGrid.GetCellRange(RowNumber, SwapGrid.Cols[ColDblSpread].Index).Clear(C1.Win.C1FlexGrid.ClearFlags.All);
    else
    {
      SwapGrid[RowNumber, ColDblSpread] = DblSpread;
      cr = SwapGrid.GetCellRange(RowNumber, SwapGrid.Cols[ColDblSpread].Index);
      cr.Style = StyleBidDblBoldSpread;
    }
    }
    }
    

    See? Makes sense, right? :-P

    (Note for you who don't have a sense of humor: JOKE. Merely demonstrates how the above code might possibly make some sense, even whilst being a WTF. Changing the value of a property in the get function? Eugh.)

  • (cs)

    One possible (but still stupid) reason for the first one is if the function does something nasty, and you don't want to risk that a dangling function pointer might fling you into it. Of course, it could just fling you to just inside the 'if' statement...

    "Everyone is an admin day" looks like some sort of sabotage. I sincerely hope the last one is too.

    And to save everyone the trouble, "twentyspaces" contains 25 spaces.

    (WTF is a comparisment anyway?)

  • (cs) in reply to joemck
    joemck:
    hmmm... BTW, this is in Mac OS X Leopard (based on BSD)
    Try this version of sed. You know what, try figuring out how it even works. :^)
  • (cs) in reply to some coder
    some coder:
    I found this in some production code:

    int iChkShut; // variables MUST be initialized, not sure why. Funny enough, the parameter iChkShut is used (uninitialized) for comparisment a couple of rows later.

    Holy bejesus that's funny

    I think I like your improvement to the comment. Management should give you a bonus for improving the program documentation. ;->

  • moz (unregistered) in reply to foo
    foo:
    That doesn't even come close to Perl, which has "0 but true" which is 0 when used as a number but true when used as a boolean. That's a WTF built into the language.
    That's not a WTF, it's another way to do $[-1.

    "'0.0' == !'0.0'" is different, although I can't decide whether this is better or worse than PHP's "'0.0' > !'0.0' && 0.0<!0.0".

  • (cs) in reply to Richard

    #define COMMA "|"

    Richard:
    TRWTF on the twentyspaces one (as well as COMMA for that matter) is people using variable (or constant) names that describe their initial state rather than their purpose. In these cases, FIELD_SEPARATOR would have made a lot more sense.

    Another thought: It seems to have become standard industry practice to describe as "comma delimited values" ALL text files that use newlines to separate "records" and /any character at all/ to separate values on a line. So I fear that "COMMA" would appear to be a "sensible" name to a surprising number of our (possibly somewhat intellectually challenged) peers in this industry.

    (Personally, I agree with Richard: I would Refactor-Rename it to FIELD_SEPARATOR as soon as I noticed it.)

  • Jim (unregistered) in reply to Steve
    The C Programming Language:
    Since the imlementation of #define is a macro prepass, not part of the compiler proper, there are very few grammatical restrictions on what can be defined. For example, Algol fans can say
    #define then
    #define begin {
    #define end ;}
    and then write
    if ( i > 0 ) then
    
    begin
        a = 1;
        b = 2
    end</b></pre></div></BLOCKQUOTE>
    

    Well, and there is an errata for the missing «;» ?

  • \ (unregistered) in reply to Jim
    Jim:
    The C Programming Language:
    Since the imlementation of #define is a macro prepass, not part of the compiler proper, there are very few grammatical restrictions on what can be defined. For example, Algol fans can say
    #define then
    #define begin {
    #define end ;}
    and then write
    if ( i > 0 ) then
    
    begin
        a = 1;
        b = 2
    end</b></pre></div></BLOCKQUOTE>
    

    Well, and there is an errata for the missing «;» ?

    end is ";}".
  • Dekker3D (unregistered) in reply to A Nonny Mouse
    A Nonny Mouse:
    jimlangrunner:
    25th! (space)

    No, I didn't count. Had the computer do it for me.

    WTF?

    "twenty" is obviously base 12.5

    do people make jokes in base 12.5?

  • (cs)

    I think that last bit of code was the result of "morganj"'s upbringing.

    http://qdb.us/10958 (I would have linked to bash.org, but they're still down :( ).

  • Access boy (unregistered) in reply to Niels
    Niels:
        lSend = IIf(lSend = True, True, False)
    Obviously because there are other values than True and False. (FileNotFound etc.)

    In a real language I'd just have done lSend = !!lSend; for it, concise way to force a value to boolean.

    ROFL

    Since I use all 10 fingers to type, if I wanted to break the code by replacing it with something that looked almost the same I'd have used

    1Send = Not Not lSend

  • more randomer than you (unregistered) in reply to Kuba
    Kuba:
    A Nonny Mouse:
    If .Fields("CUST_NUM") = "7742" Then dtmOrderPlaced = dtmOrderPlaced End If
    looks to me like someone needed a breakpoint while debuggering
    That's why I have always been at loss why some standard C header is not forced to include something to the effect of
    #define NOP() asm("nop");
    I have a header in my library of "useful stuff" that does include this. It is quite cross-platform, too!

    Cheers, Kuba

    kuba - unsw?

  • Roddy MacKenzie (unregistered)

    I truly sympathise with Christophe Beugnet. I have seen the following pairs in different C headers .. in the same project! Much joy ensued as we tried to debug it.

    #define True 1 #define False (!True)

    #define FALSE 0 #define TRUE (!FALSE)

    #define false 1 #define true (!false)

    Reminder for BASIC & Pascal programmers: C is case sensitive, so all six definitions were live at the same time.

    Yes, it was in code converted from Pascal to bad C by at least three Pascal programmers and an automated convertor (possibly "pastoc" or "pas2c")

  • (cs) in reply to Dekker3D
    Dekker3D:
    A Nonny Mouse:
    jimlangrunner:
    25th! (space)

    No, I didn't count. Had the computer do it for me.

    WTF?

    "twenty" is obviously base 12.5
    do people make jokes in base 12.5?
    Round here? Yes.

  • Tina Woodward (unregistered)

    I just finished a Doom game and am about to start Duke Nukem 3D. The high res packs make these games look like brand new on new PC's.

    Jiff www.anonymize.us.tc

  • iToad (unregistered) in reply to Thief^
    Thief^:
    andem:
    if((0 == DblSpread) || (0 == DblSpread))

    This comparison order is actually an old trick to avoid unintentional assignment in if() clause from the days when IDEs/compilers didn't warn about those. Constant = Variable assignment resulted in compiler error and saved some debugging time.

    That's not the wtf, the wtf is that it's exactly the same comparison twice.

    It's actually a bug. To cover both cases, the programmer meant to type:

    if((0 == DblSpread) || (DblSpread == 0))

    This covers both possible variants of the Boolean expression, and therefore is twice as likely to detect DblSpread being equal to zero, as using either term by itself.

  • someone (unregistered) in reply to iToad
    iToad:
    Thief^:
    andem:
    if((0 == DblSpread) || (0 == DblSpread))

    This comparison order is actually an old trick to avoid unintentional assignment in if() clause from the days when IDEs/compilers didn't warn about those. Constant = Variable assignment resulted in compiler error and saved some debugging time.

    That's not the wtf, the wtf is that it's exactly the same comparison twice.

    It's actually a bug. To cover both cases, the programmer meant to type:

    if((0 == DblSpread) || (DblSpread == 0))

    This covers both possible variants of the Boolean expression, and therefore is twice as likely to detect DblSpread being equal to zero, as using either term by itself.

    Just being pedantic: With operator overloading

    0 == DblSpread

    could return something different than

    DblSpread == 0

    (I love operator overloading.)

Leave a comment on “A Smorgasbord of Classics”

Log In or post as a guest

Replying to comment #:

« Return to Article