Nope this isn’t as simple as the title suggests!
As a lot of us know, the definition of _BV() in the Atmel AVR toolchain contains a bug which causes it to fail for any bit value above 15.
One solution is to redefine it like this:
#ifdef _BV #undef _BV #define _BV(b)(1UL<<b) #endif
This works, but then fails if the bit value is larger than 31 (don’t yell at me to use bit(b) – I know about that and that’s not what I am asking!)
Changing the value of 1 to from “1UL” to “1ULL” makes it work all the way up to 64
Unfortunately, using “1ULL” takes up a bit more flash than “1UL”. So, what I want to do is something like this (pseudo-code):
#ifdef _BV #undef _BV // undefine any current _BV macro #if sizeof(b)==1 #define _BV(b)(((uint8_t)(1))<<b) // if 8 bit #elseif sizeof(b)==2 #define _BV(b)(((uint16_t)(1))<<b) // if 16 bit #elseif sizeof(b)==4 #define _BV(b)(((uint32_t)(1))<<b) // if 32 bit #elseif sizeof(b)==8 #define _BV(b)(((uint64_t)(1))<<b) // if (unlikely but possible) 64 bit #endif
This way, the macro will only take up as much space as necessary. Is this kind of thing possible? I know that it could be done with a small function, but I would rather have the “no overhead” qualities of a macro.
My gut says “hope it can’t be done” because there is no “b” to test until after the macro is defined (can it reside IN the macro?)