为什么C语言没有二进制文字?

53

我经常希望能够像这样在 c 中做某些事情:

val1 &= 0b00001111; //clear high nibble
val2 |= 0b01000000; //set bit 7
val3 &= ~0b00010000; //clear bit 5

这种语法似乎是C语言中非常有用的补充,我想不出任何缺点,而且在位操作比较常见的低级语言中,它似乎是一件很自然的事情。

编辑:我看到了其他一些很好的替代方案,但当存在更复杂的掩码时,它们都会崩溃。例如,如果reg是控制微控制器上I/O引脚的寄存器,并且我想同时将2、3和7号引脚设置为高电平,我可以写reg = 0x46;,但我需要花费10秒钟思考它(并且每次阅读这些代码之后的一两天里,我可能还需要再花费10秒钟),或者我可以写reg = (1 << 1) | (1 << 2) | (1 << 6);,但我个人认为这比只需编写`reg = 0b01000110;' 要不清晰得多。尽管我同意这种方法无法很好地扩展到8位或16位架构以外。不过我从来没有需要制作32位掩码。


2
它有十六进制,我认为这甚至更好,如果你花10分钟来感受关系。 - vroomfondel
8
C语言有“二进制”字面量,但只有两个:0和1。;-) - chux - Reinstate Monica
6
就这个问题而言,C++14将具有这些功能 - Nemo
2
#define B00000000 0 #define B00000001 1 #define B00000010 2 #define B00000011 3 ... #define B10100100 0xA4 ... 可能需要强制类型转换为 unsigned char - pmg
1
@AnT:更准确地说,0是一个八进制常量 - chqrlie
显示剩余7条评论
11个回答

-2
以下内容仅限于8位,尽管扩展应该很简单。虽然它不会产生C语言的字面常量,但会生成编译时常量。
#define B_(X) B8_("00000000" #X)
#define B8_(X) B8__(X+sizeof(X)-9)
#define B8__(X) \
        (B___((X), 7) | B___((X), 6) | B___((X), 5) | B___((X), 4) | \
         B___((X), 3) | B___((X), 2) | B___((X), 1) | B___((X), 0))
#define B___(X, I) (((X)[7-(I)] - '0') << (I))

以下函数编译成代码后返回常量18
int test(void) {
    return B_(10010);
}

在线尝试!

如果性能不是问题,你可以做一些更简单的事情:

#define B_(x) strtoull(#x, 0, 2)

3
每次运行这段代码时,都会进行三次运行时字符串解码,这对性能不利。 - David Given
2
@DavidGiven,对于编译器来说,将值优化为编译时常量是微不足道的。不执行运行时解码。 - sleblanc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接