A lot of Arduino sketches make fairly heavy use of the “boolean” type – after all, digitalRead() and digitalWrite() use TRUE/FALSE or HIGH/LOW don’t they? Why not use boolean? It seems intuitive, after all.
Well, there are many, many reasons not to use boolean. I think it is one of the biggest mistakes in the Arduino environment.
Everything on the AVR is at least 8 bits wide. If I write to a memory location, register, or port, I need to write all 8 bits. If I read, I need to read all 8 bits. A boolean is just a single bit. We can infer from this that we are going to need to do some work to represent a boolean.
The next thing we need to realise is how C evaluates true and false on various types. This is really simple. If every bit in an integer is set to 0, evaluate this as false. Otherwise, true. This stems from the way that processors work internally, using the Z (zero) flag to determine if a branch should be taken or not.
This means that 0xA6 is as true as 0x01 is as true as 0xFF. The only thing that evaluates to false is 0x00.
These two things – the smallest native memory location being 8 bits wide, and the evaluation of 0x00 as false – make it really easy to implement a boolean. We just use an 8-bit unsigned integer and call it boolean. We then assigned 0x00 to FALSE and something non-zero to TRUE.
typedef uint8_t boolean;
#define FALSE 0
#define TRUE 1
This is almost exactly how Arduino implements booleans. It works, but it hides some of the fundamental concepts you need to understand to efficiently write code for AVR microcontrollers.
What are the problems with this?
- You are wasting 7 bits of a 8 bit memory location or register. This is fine on a modern PC, but on an AVR microcontroller, you only have 32 registers and limited RAM.
- This is hugely exacerbated when you have build arrays of boolean. Having an array of bits is very common (for example, in serial transmission). “boolean arr_of_bool” uses 32 bytes to store 32 bits. Use “uint8_t arr_of_uint8” instead, and learn how to set bits.
- It hides the concept that the only thing that evaluates to false is 0. You often see “if (variable == true)” in Arduino code. It just isn’t required. Even worse is “if (variable ? TRUE : FALSE)”. Ouch – I’ve even seen this tenary operator inside a comparison in a library before.
- It hides the concept of setting individual bits in a byte. You really cannot go very far in embedded systems without knowing about this.
- It is not a native C type. Move to another platform or compiler and you will need to re-implement it. Should it be bool or boolean? true or TRUE? HIGH or LOW?
I’d be really keen to see Arduino move towards native data types, but I can’t see it happening.