Jason was investigating a bug in a bitmask. It should have been set to 0b11
, but someone had set it to just plain decimal 11
. The line responsible looked like this:
byte number = (byte) 11;
This code takes the decimal number 11, casts it to a byte, and stores it in a byte, leaving us with the decimal number 11.
Curious, Jason checked the blame and saw that one of their senior-most devs was responsible. Figuring this was a good opportunity to poke a little fun at the dev for a silly mistake like this, Jason sent them a message about the difficulties of telling apart decimal values and binary values when the decimal value only contained ones and zeroes.
“What are you talking about?” the dev replied back. “The (byte)
operator tells the compiler that the number is in binary.”
Concerned by that reply, Jason started checking the rest of the code. And sure enough, many places in the code, the senior dev had followed this convention. Many of them were wrong, and just hadn’t turned into a bug yet. One of two were coincidentally setting the important bits anyway.
Now, in a vague “defense” of what the senior dev was trying to do, C doesn’t have a standard way of specifying binary literals. GCC and Clang both have a non-standard extension which lets you do 0b11
, but that’s not standard. So I understand the instinct- “there should be an easy way to do this,” even if anyone with more than a week’s experience *should have known better*.
But the real moral of the story is: don’t use bitmasks without also using constants. It never should have been written with literals, it should have been written as byte number = FLAG_A | FLAG_B
. The #define
for the flags could be integer constants, or if you’re feeling spicy about it, bitshift operations: #define FLAG_A = (1 << 1)
. Then you don’t need binary literals, and also your code is actually readable for humans.
It was difficult to track down all the places where this misguided convention for binary literals was followed, as it was hard to tell the difference between that and a legitimate cast to byte
. Fortunately, there weren’t that many places where bitmasks were getting set.
Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!
Source: Read MoreÂ