Bool 'value' is true, but (value == true) yields false



  • True story.

    It all began when I forgot to properly initialize my member variable, which of course deserves harsh punishment. Still I was a little flabbergasted at the form of punishment my combination of MSVC (2010) and googletest devised...

    googletest seems to intentionally write some random patterns in memory prior to running my code. So every time I forget to initialize a member, I get some weird value, often way outside the range allowed by the type.

    So in this case. My boolean had a value of 0x14 internally.

    For the MSVC watch, a value of 0x14 seemed to indicate a 'true' boolean value, whereas the expressionq (sic) (value == true) yielded 'false'.

    So, would writing code like
    @if (value)@
    potentially yield different results than writing
    @if (value == true)@
    ?

    It certainly looks like.

    I also wonder if the C++ standard has anything to say about bool behavior, and how other compilers (specifically gcc) would behave in such a case.

    Side note:
    The word "expressionq" without the "q" but followed by a "(" seems not to pass some test by this forum's parser. It is [removed]


  • Lifetime Qt Champion

    Hi,

    IIRC a boolean is an integer type that can have two values true or false (true = 1 and false = 0) however nothing forbids you to put something else in it.



  • I found "this":http://stackoverflow.com/questions/356726/is-bool-a-basic-datatype-in-c informative.

    I don't see the point of @if(value == true)@

    test:
    [removed]

    that is odd i wonder what other words do that



  • [quote author="Buckets" date="1379456713"]
    I don't see the point of @if(value == true)@
    [/quote]

    Some of my colleagues like to code in that style. So far, I only saw it as a different way to achieve the same.
    However, if the style of coding can suddenly change the outcome, that's something to be aware of.



  • @#include <cstdio>
    int main(int argc, char* argv[]) {
    bool a=false;
    ((char)&a)=0x14;
    if(a) printf("a=%x\n",a);
    if(a==true) printf("true a=%x\n",a);
    return 0;
    }@
    Output is:
    a=14
    Strange.



  • bool has three states true (1), true (non-Zero), or false (0).

    true (1) and true (non-Zero) will act the same way within a decision, however they might not be equal to one another.

    using @if(value == true) @

    is extra typing (only 6-8 characters) that can result in obscure behaviors that can be avoided. If your colleagues want to use [object Object] == true@

    to get three different states, they should just use and int to make it clearer for someone in the future who is reading/revising the code. If they are using the expression to show they are checking for true, they could just put a comment after the expression to state their intent.



  • Once again, I miss the "rate this up" button next to replies. Thanks for your input!


  • Moderators

    As it is stated between the lines of some of the previous posts, the behavior stems from an integer comparison rather than a bool comparison.

    It is the first time I have seen such comparison. I would it is highly uncommon. In addition, it is also somewhat dangerous, since the behaviour is unpredictable as you have already found out. Since bool is stored, depending on the memory packing used, at least as a byte, the likelihood of such an undesired behaviour is high.

    As Buckets states without the extra characters the statement is clearer and if someone relies on the three state behaviour there is an int casting more than welcome for clarity.

    However, I do not agree with his statement that at least some comments should be included. You might end up with more different behaviours as you have encountered so far. The compiler cast the values to int before carrying out the comparison. I am not sure if this is the case for all compilers. One would need to check, what the standard says in this respect in order to know if it is reasonably safe,

    IMHO it is safer to stay with common practice. Certainly sometimes it confuses people to read
    @
    if ( value )
    @

    maybe one could use
    @
    if ( value ) // == true
    @

    to avoid such a confusion. This combines common practice with clarity for developers who consider the first version as confusing.



  • We would never intentionally use 'bool' in this weird three-state form. So ideally, we should never encounter this issue.

    While I personally prefer the form
    @if (value)@

    I can't very well argue that
    @if (value == true)@
    is wrong. It's the same form I would use for any other integral type

    @if (i == 1) ...;
    if (ptr == 0) ...
    if (enum == eSomething)@

    and so on. Why should this form be wrong for bool?

    For me, there is no clear indication which of those forms is "right" and which is "wrong". As with many things, it is a matter of personal taste - as long as you know about, and consider the consequences.


  • Moderators

    The question is if you have to argue right and wrong. The bit thinking of computer experts ends very often in limiting everything to right and wrong, because the bit is either 0 or 1.

    These exact states have been used to define true and false for bool. However, for performance reasons C++ uses larger entities (at least a byte as noted before) to represent true and false. In general this is not an issue as long everything stays consistent.

    I have had a look into Stroustrop's book yesterday. Apparently, it is not a flaw in the definition of C++ that bools are represented by integers. Apparently, there are some more thoughts behind.
    He uses an example in his C++-"bible" (The C++ Programming Language)
    @
    void g()
    {
    bool a = true;
    bool b = true;

    bool x = a + b;    // a + b is 2 and also true
    bool y = a | b;    // a | b is 1 and also true
    

    }
    @

    Therefore, extending this example will have correct behaviour for

    @
    if ( x )
    {
    .... // will be executed
    }
    if ( y )
    {
    .... // will be executed
    }
    @

    but not for
    @
    if ( x == true )
    {
    .... // will NOT be executed
    }
    if ( y == true )
    {
    .... // will be executed
    }
    @

    Note that both x and y are bools.
    When writing my earlier response I forgot to mention this part.

    Though the behavior you noted is not just because of uninitialized memory, but maybe also by intention when someone is following the thoughts of Bjarne Stroustrup.

    The only way of correct handling is probably
    @
    if ( ! ( value != false ) )
    @

    which is really obscure. Possibly this is working as well.
    @
    if ( ! value == ! true )
    @



  • I get your point. Fortunately, things like

    @ bool x = a + b; // a + b is 2 and also true@

    get caught by static code analysis.


  • Moderators

    [quote author="Asperamanca" date="1379590555"]I get your point. Fortunately, things like

    @ bool x = a + b; // a + b is 2 and also true@

    get caught by static code analysis.[/quote]

    For your code you are completely right.

    However, in general, it is a very dangerous (wrong) coding style in view of Bjarne Stroustrup's intentions. As soon as you use code not following your thoughts, logic and rules, you are in trouble.
    Who knows, if Qt does always return a perfect "true" ?



  • In C/C++ only false is defined as zero; true is defined just as !(false);
    so
    @
    if (value)
    @

    is different from
    @
    if (value == true) // this definition can be false due to definition above
    @
    I've faced this problem using my own library in different program I've used.
    If value is different from zero, so "true" in the target compiler it could be not true due to different definition in the target compiler.
    e.g. value = 15 (different from zero, so true value)
    target compiler used a true = 16 (since it is defined as different from zero can be any integer value)
    so
    @
    value == true // 15 == 16 results as false
    value == false // gives always the same result since false is defined as zero in all compilers.
    @

    This behaviour can happen when you use different compiler to build a library/component and use that in other program built with another compiler.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.