Go Down

Topic: Compiler bug: bool (Read 5115 times) previous topic - next topic

flounder

Code: [Select]
unsigned long bits;
unsigned long mask;
    ...
    bits = ...something...;
    ...
    mask = ...something...;
    ...
    bool action = bits & mask;
    if(action)
      ...


The problem I had in compiling this is that the C++ standard says that if the RHS is an integer type, then the coercion is to 'false' if the RHS == 0 and 'true' if the RHS != 0. 

I lost a week because the compiler did this wrong.

It took quite a while to discover (since this was being debugged on a Tiny85) that the result was based solely on the state of the low-order 8 bits. 

It was easily fixed by rewriting the assignment as

   
Code: [Select]
bool action = (bits & mask) != 0;

But I carefully re-read the C++ standard, and that should have been unnecessary.  Furthermore, it only happened when compiling for the Tiny85, which does not really support serial port debugging.  When I compiled it for an Arduino board, it compiled the correct code, which is part of the reason it took a week to find the problem.  I did not expect it would obey the standard for one platform and violate it for another.

For the Tiny85, it compiled the code as if it had been written
   
Code: [Select]
bool action = ((bits & mask) & 0xFF) != 0;
       Joe

pert

it only happened when compiling for the Tiny85
Which hardware package were you using?

When I compiled it for an Arduino board, it compiled the correct code
Which Arduino board?

flounder

Hardware package?  I selected the Board Type "AtTiny85".

Both the Arduino R3 and the Adafruit Feather U4.  Both of which reported (via Serial.print()) the correct values for the bits, mask, and action  variables.

pert

Hardware package?  I selected the Board Type "AtTiny85".
The Arduino IDE doesn't have that board type by default. You need to install a 3rd party hardware package (sometimes referred to as a "core") to add it. There are multiple packages available for ATtiny85, which was it?

robtillaart


Seen similar problems with bool / boolean in the past.

It can be solved by a !! construct, the "not not", which takes care that any value is correctly 'casted' to bool.

Code: [Select]

void setup()
{
  Serial.begin(115200);

  unsigned long bits = 0x01000000;
  unsigned long mask = 0x01000000;

  Serial.println(bits & mask);

  Serial.println((bits & mask) != 0);
  Serial.println((bits & mask) > 0);

  Serial.println((bits & mask) == true);    // this is tricky
  Serial.println((bits & mask) != false);

  Serial.println(!!(bits & mask) == true);
  Serial.println(!!(bits & mask) != false);
  Serial.println(!!(bits & mask));

}

void loop() {}
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Go Up