• (nodebb)

    Issues like this are why comparing booleans to see if they are equal to true (or True) (or TRUE) makes me want to stab people with the GAU-8 I keep in my back pocket.

    Ultimately, all we really want to know about boolean values is whether they are true-ish or false-ish, not whether they are equal to true or equal to false. (Truthy versus falsy is a different matter, by the way.)

    I would also say that in this case, part of the problem is the name. Call it "IS_ONLINE" and people will be slightly less prone to misusing it:

    IF doodad.IS_ONLINE = True
    

    That looks really weird, but:

    IF doodad.IS_ONLINE
    

    reads nicely.

  • Steve Taylor (unregistered)

    One might ask the simple question of whether the code snippet "= True" ever, under any circumstances, an appropriate way to express anything. Possibly the real WTF is a language where boolean=True evaluates to a logically different differently value to the boolean.

  • Ni_Knight (unregistered)

    Reading this brought back nightmares from my old days writing complete systems using only MS Office and VBA in a highly regulated environment. The things I did back then will haunt me for the rest of my life. But don't judge me - I was young, inexperienced and had no access to proper development environments.

  • Christian (unregistered)

    There are coding styles that require a explicit query for truth values. And also one could argue that it's a bad choice in the style or not, they exist. But even in this cases it's a much safer choice to write compares like "x == false" or "x != false". I stopped comparing anything with "true" after I have searched for a similar problem once. Never compare with "true". If necessary: Compare with "false". I haven't found a language yet where "false" hasn't been 0.

  • (nodebb)

    Good Ol' 8 K Microsoft BASIC used the value -1 for True because it is a pattern with all bits set. But would accept non zero as True if I remember correctly. It meant that AND could be implemented with multiplication and OR with +additionif you were so cheap.

    C does thi haves too : struct { int bit :1; }

    bit is a signed 1 bit integer with values -1 and 0. It can fry your brain if you dont spot this one..

    struct { unsigned intu bit : 1; }

    makes ubit have the values +1 and 0 for true and false . If you spend time programming microcontrollers and use structs to pick apart registers this can catch you out when you use a bit in a calculation assuming its +1 and 0 for True and False.

    Addendum 2020-06-01 09:02: I meant ubit not intu above ..

  • LCrawford (unregistered)

    Old programmers got used to checking only for the false case, because 0 is the most commonly used value for false. Even among different C libraries, one may return 0x00FF for true while another returns 0xFFFF (-1) and yet another returns 1.

    TRWTF was the COM library not properly returning VARIANT_BOOL .

  • C++ sucks (unregistered)

    Well, in all honesty, în C++ the value 0 is false and any other value is true.

  • Charles Shapiro (unregistered)

    And of course Real Old-Line C programmers often used 0 for "SUCCESS" and any other value for "FAILURE", on the assumption that success is a unique condition but you could store an integer failure reason in the variable. This could cause much fun if you misread the doc and assume that some routine is returning TRUE or FALSE..

  • (nodebb) in reply to mike_james

    C does thi haves too : struct { int bit :1; }

    bit is a signed 1 bit integer with values -1 and 0. It can fry your brain if you dont spot this one..

    What will really fry your brain is that the only portable value you can put into bit and reliably get it back is 0, partly because of the vagaries of the representation of signed int(1) and partly because for bitfields an int of unspecified signedness like this doesn't have to be signed.

    Not to mention that it doesn't behave like a proper boolean type. This:

      struct { int bit :1; } boolvar;
    
      boolvar.bit = 2;
    
      printf("boolvar.bit is %d\n", boolvar.bit);
    

    outputs:

    boolvar.bit is 0
    

    (1) For twos complement, it will, indeed, be 0 or -1. For ones complement, it will be +0 or -0. For sign-and-magnitude, it isn't remotely clear what that a one-bit integer can possibly represent.

  • (nodebb)

    Of course, this could also have been avoided by the common WTF head-scratcher:

    if (not not hardware.ONLINE) == True

  • Appalled (unregistered)

    As I recall it wasn't just VB, it was also Access. I remembering coding Where Clauses and Joins as BlahDeeDah = -1 in hand-coded SQL statements. Truly sucked the times I got it backwards when switching languages constantly in a varied environment. But that's what testing is for.

  • Anon (unregistered)

    And what if ONLINE == FILE_NOT_FOUND?

  • Anonymous') OR 1=1; DROP TABLE wtf; -- (unregistered)

    Raymond Chen covered this topic in 2004: https://devblogs.microsoft.com/oldnewthing/20041222-00/?p=36923

  • (nodebb) in reply to mike_james

    "If you spend time programming microcontrollers and use structs to pick apart registers this can catch you out when you use a bit in a calculation assuming its +1 and 0 for True and False."

    Of course if you spend any time programming MCUs you should know that a bitfield register should never be represented by a) a signed int or b) a bitfield struct in the first place :P

    (The reasons being that you are very close to the hardware at that level, so access methods matter a great deal and should be programmed explicitly, struct layouts are subject to toolchain settings, and the strategy the compiler will emit for accessing bitfield members is at best opaque and at worst unpredictable, especially when you want to set or clear multiple bits simultaneously. )

  • Officer Johnny Holzkopf (unregistered) in reply to Steve_The_Cynic

    If you use the "is" prefix, testing for = true or = false already feels wrong in the "mental language phase", before transitioning to the "source code phase". Things like "If foobar.isOnline Then" is more logical than "If foobar.isOnline = True Then". The "is" indicates already that it either is, or is not, not is. No need to talk about this being or not being is true or not true or false or file not found. However, if you do not use "is", but instead want to query a status with a specific set of values for comparison, like "If foobar.status = Online Then" (status: Online, Offline, Blocked, NotSure) or "foobar.presence = NotPresent Then" (presence: Present, NotPresent, CannotDetermine), using enums is probably the better thing to do. Again, that conditional doesn't have to be compared to true or false either (no nonsense like "If (foobar.status = Online) = True Then" is needed, except you're paid by characters added to codebase).

  • Stella (unregistered)

    Well, in C, I've seen a lot of explicit comparisons to true and false, with "bool" being defined as an int. Now, when "x!=true", that means x is (in the usual case) anything but 1. If "x==false", that (usually) means "x is zero". Which means, if x is 2 (or FILE_NOT_FOUND, or anything but true or false) "x==true" and "x==false" both evaluate to false. "Truthy"and "falsy" are no new terms introduced by javascript and the like. They've been there since forever. This is the true(thy) evil.

  • Anon (unregistered) in reply to Steve Taylor

    ONLINE property is int, not boolean, the COM wizards miss-declared it.

  • (nodebb) in reply to Officer Johnny Holzkopf

    @Officer Johnny Holzkopf: yes, that was my point.

  • Old timer (unregistered)

    TRWTF is the 8086 architecture, which has a machine code instruction for testing if an integer is negative or not, and a twos-complement representation of negative numbers -- leading to simple machine-mapped tests for 0 or FFFF.

  • Have you tried turning it off, and then on again? (unregistered) in reply to mike_james

    C does thi haves too : struct { int bit :1; } bit is a signed 1 bit integer with values -1 and 0. It can fry your brain if you dont spot this one..

    The signedness of a bit field is implementation defined, so it could be signed or unsigned.

    And if signed, as someone else pointed out, it could use sign-and-magnitude, 1-complement, or 2-complement to represent signed types, the standard allows for all three.

    Plenty of things to make you go "Huh, now why did it do that?" for the unwary.

  • Antoine (unregistered) in reply to Appalled

    MS access still uses -1 for true. Not in the past, still present. And I suspect Excel does the same, although it is less visible to the user.

  • Jajcus (unregistered)

    I haven't found a language yet where "false" hasn't been 0.

    $ /bin/true ; echo $?
    0
    $ /bin/false ; echo $?
    1
    
  • hartmut holzgraefe (google)

    Others already mentioned that TRUE=-1 is a tradition that goes all the way back to Microsoft BASIC for 8bit computers.

    We were bitten by this when porting some Access application, making it a multi user capable web frontend while maintaining most of the Access applications look and feel (a WTF by itself).

    The "database guy" on the project used some tool to do the database conversion from the original Access/JetEngine data to Oracle, and for some reason unknown to us (probably just using the default suggestion made by the conversion tool?), and noticed too late in the project to get this changed, chose to convert Access "boolean" columns to "VARCHAR2(1)".

    Not "CHAR(1)", not "VARCHAR(1)" ... the "can store more than 255 characters" "VARCHAR2" ...

    Now what happened during conversion was that the numerical value stored in the "boolean" column in Access (apparently actually a numeric column) was converted to text, and then stored in the new column on the Oracle side.

    And as TRUE was -1, it became "-1", and then got truncated to just one character "-".

    So this system ended up having "0" for false, and "-" for true, in its database, and code like this on the application side:

    if (row->flag == '-') { // do something as flag is set }

  • (nodebb) in reply to mike_james

    I always thought that AND and OR were bitwise operators in that version of BASIC. This compares to e.g. Sinclair Basic, which made x AND y equivalent to x*NOT NOT y (so somewhat like y && x but not lazy).

  • MiserableOldGit (unregistered)

    Personally I was fine with the VB thingies treating true as -1, I do remember someone explaining to me (convincingly) why it was actually "correct", but I can't remember the logic and can't seem to find the argument on google.

    It is an irrelevance anyway as the problem is confusing the VB coders by telling them you are giving them one of their nice little booleans, when you are not ... I would have thought it would typecast to a Long based on what's been said there, but variant is possible and always a horror show. We had Option Explicit at least, we also needed Option UnderNoCirumstancesUseAnyFuckingVariants. On the other hand, unless the VB coders were total noobs they should have known that APIs and COM objects and the rest never seem to do what they say on the tin, especially in-house ones.

    If you give VB a number it takes 0 as false and any non-zero as true so the nasty anti-pattern of "if some-value = true then" has bitten them here*, if they'd just written "if some-value then" their code either would have worked as expected or blown some sort of mis-matched type error at them which should have led to confused swearing and eventually, enlightenment.

    Mind you, I would say that for a strongly typed language to do the kind of implicit casting that accepts "oHardware.ONLINE = True" and then doesn't apply the non-zero logic is a big WTF. I suppose it just cast True to -1 and rumbled on, yuk.

    *I think it's horrid unless there's some real reason of clarity to use it, however the whizz-kids at MS are quite fine telling newbies to do it that way! https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/operators-and-expressions/boolean-expressions

  • Only Reason For Commenting (unregistered) in reply to C++ sucks

    Well, yes. One of the many things that Remy has (unintentionally) misrepresented.

    "But this is a C++ boolean. Defined so that true is one and false is zero."

    Oddly, we've moved on from C (pre C99) with no Booleans, to C++ Booleans, which as far as I am aware have always been 0 or 1. Of course, there's the legacy glitch that in an if-expr in C++ you supply anything other than 0, you get a free pass as true. But then that appears to be the complete opposite to the OP complaint.

    Me, as a (forced) disciple of Martin Richards and BCPL, I've always favoured the idea of "false" being all binary 1s and "true" being all binary zeros. But actually it doesn't matter. If you're a programmer, writing across an interface to another language, and you cannot manage a simple Boolean marshalling, then why don't you go find a more rewarding job, like clipping coupons?

    Bah. Kids these days. Get off my domain-specific lawn.

  • !!TRUE (unregistered)

    VB using -1 for true is no more WTFy than the C declaration using 1. In both cases the real definition of true is 'anything non zero' and no one value is better than any other.

    There's actually an argument that -1 is a better 'true' value because all bits of it are true.

    This is why the 'if ( xxx == true ) ' anti-pattern is so hazardous - sometimes it's not only superfluous but actually changes the meaning of the test.

  • Richard (unregistered)

    Nobody's pointed out the horrors of VB6's "Dim x As New Foo" yet. Am I the only one who remembers what terrible things that would do?

    Every time you use that variable, the VB6 compiler is going to check whether it's null, and if it is, create a new instance of that class and store it in the variable.

    Thankfully they fixed that behaviour in VB.NET.

  • (nodebb)

    This has been known for many decades..... NEVER compare to "true". If you are going to compare, then compare to false which is (almost) always 0 with true being defined as "non-zero" (though of course the literal true must have a specific bit pattern).

  • Daniel (unregistered)

    It's odd that you as a supposed veteran programmer react to TRUE being something else than 1. There's nothing wrong here. By all conventions 0 is false and everything else is true.

Leave a comment on “Don't be so Negative Online”

Log In or post as a guest

Replying to comment #:

« Return to Article