问题描述
在我正在处理的一段代码中,如果某些unsigned long
为真,则需要在_Bool
上加1。
我一直在使用
unsigned long l;
_Bool b;
... //stuff happens to both variables
if(b)
++l;
但是我在C标准中读到_Bool
类型被归类为“标准无符号整数类型”之一,并且保证将true表示为1,将false表示为0。
我用这个看似等效的表达式替换了代码
unsigned long l;
_Bool b;
... //stuff happens to both variables
l+=b;
我的编译器没有抱怨,它似乎运行得很好。
这是否可以保证正常工作,还是我只是在编译器中利用_Bool的实现?
解决方法
几乎可以保证运行。
标准并没有完全说明_Bool
对象只能容纳值0和1。实际上sizeof(_Bool)
至少为1,这意味着它至少具有8位,这表示它原则上可以包含至少256个不同的值。
如果您为b
赋值的代码相当合理,则可以放心地假定其值为0或1。从其他类型到_Bool
的所有转换都可以保证产生的值为0或1。
但是您可以在_Bool
对象中存储0或1以外的值,尽管这样做的任何方法都可能具有不确定的行为。
一个例子:
#include <stdio.h>
#include <string.h>
int main(void) {
_Bool b;
char c = 42;
memcpy(&b,&c,1);
long n = 0;
n += b;
printf("n = %ld\n",n);
}
我系统上的输出是
n = 42
但是,只要您不做这种愚蠢的事情,并以最小的尊重对待_Bool
,您就可以没事。
这可以保证工作吗
是的,C语言中的布尔值只是整数,因此在我所知道的任何编译器中,将布尔值添加到整数都是完全可以接受的。 C是弱类型的,因此布尔值和整数值之间没有明显区别。声明为_Bool
的变量的唯一含义是它会自动将分配给它的任何值转换为1或0。
_Bool x = 3; //x will be 1
int y = 7;
int z = y + x; //z will be 8