Compiler bug: bool

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

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
bool action = ((bits & mask) & 0xFF) != 0;
Joe

flounder:
it only happened when compiling for the Tiny85

Which hardware package were you using?

flounder:
When I compiled it for an Arduino board, it compiled the correct code

Which Arduino board?

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.

flounder:
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?

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.

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() {}