c++中的布尔乘法
Boolean multiplication in c++?
考虑以下内容:
inline unsigned int f1(const unsigned int i, const bool b) {return b ? i : 0;}
inline unsigned int f2(const unsigned int i, const bool b) {return b*i;}
f2
的语法更紧凑,但是标准是否保证f1
和f2
是严格等价的呢?
此外,如果我希望编译器在编译时知道b
和i
的情况下优化这个表达式,我应该选择哪个版本?
嗯,是的,两者是等价的。bool
是整型,true
保证在整型上下文中转换为1
, false
保证在整型上下文中转换为0
。
(反过来也成立,即非零整数值保证在布尔上下文中转换为true
,而零整数值保证在布尔上下文中转换为false
)
由于您正在使用无符号类型,因此可以很容易地提出其他可能基于位的但完全可移植的相同内容的实现,例如
i & -(unsigned) b
尽管一个好的编译器应该能够为你的任何版本选择最好的实现。
注:尽管令我非常惊讶的是,GCC 4.1.2几乎完全按照字面意思编译了这三个变体,也就是说,它在基于乘法的变体中使用了机器乘法指令。在?:
变体上使用cmovne
指令使其无分支是足够聪明的,这很可能使其成为最有效的实现。
是。在表达式中使用true
是1
, false
是0
,这是安全的,并且可以保证:
c++ 11日积分促销,4.5 :
bool类型的右值可以转换为int类型的右值,使用False变为0,true变为1。
编译器将使用隐式转换从b
生成unsigned int
,所以,是的,这应该可以工作。您通过简单的乘法跳过了条件检查。哪一个更有效/更快?不知道。我认为一个好的编译器很可能会优化这两个版本。
哎呀,下面的代码
inline unsigned int f1(const unsigned int i, const bool b) {return b ? i : 0;}
inline unsigned int f2(const unsigned int i, const bool b) {return b*i;}
int main()
{
volatile unsigned int i = f1(42, true);
volatile unsigned int j = f2(42, true);
}
使用gcc -O2编译生成如下程序集:
.file "test.cpp"
.def ___main; .scl 2; .type 32; .endef
.section .text.startup,"x"
.p2align 2,,3
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
LFB2:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
subl $16, %esp
call ___main
movl $42, 8(%esp) // i
movl $42, 12(%esp) // j
xorl %eax, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE2:
可以看到,f1
和f2
的空间都不大了。
就c++标准而言,编译器可以做任何关于优化的事情,只要它不改变可观察的行为( As if规则)。
相关文章:
- 一个关于在C++中重载布尔运算符的问题
- 提升精神:解析布尔表达式并简化为规范范式
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 线程之间的布尔停止信号
- 布尔比较运算符是如何在C++中工作的
- 变量定义到C++布尔值转换
- 如何确保在使用基于布尔值的两个方法之一调用方法时避免分支预测错误
- 隐式常量/非常量运算符布尔
- 如何编写一个使用n倍三元条件语句的C++布尔函数
- 如何在 c++ 中让布尔变量返回为 0 或 1 而不是真或假?
- 重载更少,则运算符返回相反的布尔值
- 将布尔变量添加到 int
- 为什么布尔开关语句有编译器警告?
- 将此布尔值传递给此函数的最有效方法是什么?
- 如何使布尔变量仅在设置为 true 时才为真?
- 为什么我不能在返回 const 的布尔函数中为类成员变量赋值?C++
- 程序中的布尔函数返回输入的范围无论如何都是无效的
- 当我尝试通过 arduino 上的引用传递布尔数组时出现问题
- 如何设置 c++ 类的布尔值?
- 使用 MAKEWORD / MAKEWPARAM 使用布尔值而不是布尔值