假设我有两个可能有副作用的函数,并返回布尔值。 (bool
中定义了<stdbool.h>
,因此将bool
定义为_Bool
类型
bool tweedledee(MyState *pmystate);
bool tweedledum(MyState *pmystate);
使用按位运算符组合它们是否安全?
bool both_tweedles = tweedledee(&mystate) & tweedledum(&mystate);
或
bool either_tweedle = tweedledee(&mystate) | tweedledum(&mystate);
我传统上使用逻辑运算符&&
或||
;我正在开发一个项目,我的团队成员正在使用按位运算符,因为这些函数可能有副作用,我们希望发生两个函数调用。 (逻辑运算符为short-circuiting。)
我唯一的保留是我不确定返回bool
的函数是否可以安全地假设返回1和0,而不是作为true
的替代值。
仅作为一个例子:如果有人将邪恶实施如下,该怎么办?
bool tweedledee(MyState *pmystate)
{
return 66;
}
bool tweedledum(MyState *pmystate)
{
return 33;
}
然后66 & 33
为0,66 | 33
为99。
答案 0 :(得分:4)
来自C99标准的第6.3.1.2/1节:
当任何标量值转换为_Bool时,如果值比较等于0,则结果为0;否则,结果是1。
如果您正在使用stdbool.h
,那么bool
(这是一个定义为_Bool
的预处理器宏)因此必须只有0或1,您的tweedledee
和tweedledum
函数无法返回该范围之外的值,并且对它们使用按位运算应该可以达到预期效果。
但是,如果tweedledee
和tweedledum
使用的某些其他bool
类型不是_Bool
,则所有投注均已关闭。
答案 1 :(得分:1)
在某种程度上,您发布的样本的安全性取决于所使用的编译器/版本/平台。
使用'&amp;'的可能更安全的实施方式会是这样的:
bool either_tweedle = ( tweedledee(&mystate) != 0 ) & ( tweedledum(&mystate) != 0 );
这可以防止tweedledee或tweedledum将0或1以外的值推入其bool返回值。
'|'你提供的案件应该是完全安全的。
答案 2 :(得分:0)
我不确定函数是否会返回 可以安全地假设bool返回1和0,而不是某些东西 否则作为true的替代值。
是。您可以放心地假设这一点并使用按位操作。
来自C99(ISO 9899:1999)7.16.3:
其余三个宏适用于
#if
预处理 指令。他们是:
true
扩展为整数常量1,
false
扩展为整数常量0和
__bool_true_false_are_defined
扩展为整数常量1。
答案 3 :(得分:-1)
如果使用逻辑运算的结果作为if语句的条件,则可能根本不执行这两个函数中的一个。如果不是这样,那么最好将结果保存在两个变量中,然后直接对结果变量进行逻辑运算。