Fundamentals of Logic



  • We had to modify some existing code inherited from another party and had some false positive error detection. The root cause:

     

    #define	FALSE	(0xFA45U)
    #define	TRUE	(0x55AAU)
    

    Yes, this is embedded code, but when FALSE != ~TRUE I don't know how to interpret the universe.



  • P.S. Yes, what got us is we had code like:

    void our_new_function(boolean bFlag)
    {
    if(bFlag)
    {
    // do stuff if flag is true
    }
    else
    {
    // do stuff if flag is false
    }
    }

    void function_from_old_supplier()
    {
    boolean bFlag;

    bFlag = FALSE;

    if(some_condition)
    {
    bFlag = TRUE;
    }

    our_new_function(bFlag); // New function call using bFlag status
    }


  •  I suppose this was an attempt to weed out the type of code posted above?  Defining FALSE and TRUE this way would enforce all C code to explicitly say if (foo==FALSE), etc.

    I would almost be fine with this if FALSE and TRUE were lowercase instead :)

     



  • @too_many_usernames said:

    Yes, this is embedded code, but when FALSE != ~TRUE I don't know how to interpret the universe.

    I think you mean FALSE != !TRUE.  The common definitions:

    #define FALSE 0
    #define TRUE !FALSE

    Will result in:

    TRUE = 1
    FALSE = 0
    ~TRUE = -2


  • @joeyadams said:

     I suppose this was an attempt to weed out the type of code posted above?  Defining FALSE and TRUE this way would enforce all C code to explicitly say if (foo==FALSE), etc.

    I would almost be fine with this if FALSE and TRUE were lowercase instead :)

     

     

    I hate when people say that I should write code like this:

    if (myBool == TRUE) { /* blah */ }

    instead of

    if (myBool) { /*blah*/ }



  • @joeyadams said:

     I suppose this was an attempt to weed out the type of code posted above?  Defining FALSE and TRUE this way would enforce all C code to explicitly say if (foo==FALSE), etc.

    I would almost be fine with this if FALSE and TRUE were lowercase instead :)

     

     

    Sadly, it was more an attempt to avoid bit corruption in an embedded application ... which already has fault-tolerante ECC memory, checksums, and watchdogs because defining any value as TRUE or FALSE will not save you from bit corruption anyway.  Instead they made it more likely for mistakes that cannot be caught by a static checker because everyone expects if ( bool ) to work as expected without having to do the silly

    if ( bool == TRUE)
    {
        // stuff if TRUE
    }
    else if (bool == FALSE)
    {
        // stuff if FALSE
    } 
    else 
    {
        // stuff if FILE_NOT_FOUND or other nonsense
    }
    

    which is what you'd really have to do to be 'safe' in this case.



  •  @tdb said:

    I think you mean FALSE != !TRUE.  The common definitions:

    #define FALSE 0
    #define TRUE !FALSE

    Will result in:

    TRUE = 1
    FALSE = 0
    ~TRUE = -2


    Essentially what you're saying is, if you expand a boolean value into a quantity that can have more than two states, you have to be careful.

    I agree with that =)

    (I would probably argue that the best implementation is FALSE = ~TRUE = !TRUE which means the only allowed values would be 0 and ~0)



  • I hate when people say that I should write code like this:

    if (myBool == TRUE) { /* blah */ }

    instead of

    if (myBool) { /*blah*/ }

    Who would say that?

    Obviously you should write it like:

    if (TRUE == myBool) { /* blah */ }

    Admittedly, this is a tongue in cheek response, and I think it's silly also, however people say the constant should come first to avoid =/== issues.


  • @Lacutis said:

    I hate when people say that I should write code like this:

    if (myBool == TRUE) { /* blah */ }

    instead of

    if (myBool) { /*blah*/ }

    Who would say that?

    Obviously you should write it like:

    if (TRUE == myBool) { /* blah */ }

    Admittedly, this is a tongue in cheek response, and I think it's silly also, however people say the constant should come first to avoid =/== issues.

     Actually, to be on the safe side, you should do:

     if (TRUE > myBool || TRUE < myBool) { /* blah */ }

     But if == is overloaded, that could be a problem.  Perhaps the best way is this:

    #if defined(__cplusplus) || defined(c_plusplus)

     if (TRUE == myBool || myBool == TRUE) { /* blah */ }

    #else

      if (TRUE > myBool || TRUE < myBool) { /* blah */ }

    #endif

    Of course, this is super-tongue-in-cheek.  I personally prefer:

    #if FALSE!=0 || TRUE!=1

    #error "WTF?!"

    #endif


Log in to reply