这种转换有多可移植?我能确信两个断言都会通过吗?
int x = 4<5;
assert(x==1);
x = 4>5;
assert(x==0);
不要问为什么。我知道它很丑。谢谢。
int x = 4<5;
完全可移植。符合标准。`bool` 到 `int` 的转换是隐式的!false
转换为零,而值true
转换为一。bool
展开为 _Bool。
[..] 展开为整数常量1的true
和展开为整数常量0的false
,[..]bool
/_Bool
类型是否可用,在C语言中,关系运算符产生的结果是int
类型,而不是bool
类型。也就是说,即使在C99中,关系运算符仍然产生int
类型的结果。 - AnT stands with Russiabool
一样的类型,但不允许其地址被取出?许多嵌入式系统使用这种类型(通常使用标识符 bit
声明)。例如,在中等范围的 PIC 上,if (bitVar1) bitVar2=1;
将是两个指令;而 if (byteVar1) byteVar2=1;
的最佳编码至少需要四个指令(在许多编译器上可能需要五个)。因此,这种类型可以提供重大的性能提升。 - supercatcmp
和setz
(或类似的指令,具体取决于byteVar1
存储的位置)。此外,如果有关于byteVar1
值的额外信息可用,则可能会进行额外的优化。 - AnT stands with Russiabitvar1
是地址0x12的第3位,而bitvar2
是地址0x45的第6位,则指令序列if (bitvar1) bitvar2=1
将是btfsc 0x12,3; 如果地址0x12的第3位未设置,则跳过下一条指令
,然后是bsf 0x45,6; 设置地址0x45的第6位
。使用这些地址的字节,最短的可能序列是:movf 0x12,w; 将W加载为值并设置Z标志(如果为零)
,movlw 0x01; 加载W为1而不影响Z
,btfss 3,2; 如果Z标志设置,则跳过下一条指令
,movwf 0x45; 将W存储到地址0x45
。 - supercatC标准的第6.5.8.6节规定:
如果指定的关系为真,则小于运算符<,大于运算符>,小于等于运算符<=和大于等于运算符>=中的每个运算符都应返回1,如果指定的关系为假,则返回0。结果的类型为int。
由于int到bool的强制转换是隐式进行的,因此似乎没有问题。这适用于Microsoft Visual C++、GCC和Intel C++编译器。在C或C++中都没有问题。
assert(x!=0)
。即使 bool(true) 可以转换为 int(1),"not false" 的断言表达式更易读。 - harperassert(4 < 5);
和assert(!(4 > 5));
呢? - Martin York(4 < 5) ? 1 : 0
。一个好的编译器可能会产生相同的机器代码,而且对于人类读者来说更清晰。 - ollb