如果两个函数都返回bool,使用按位运算符组合它们是否安全?

时间:2015-07-23 23:05:45

标签: c boolean operators c99

假设我有两个可能有副作用的函数,并返回布尔值。 (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。

4 个答案:

答案 0 :(得分:4)

来自C99标准的第6.3.1.2/1节:

  

当任何标量值转换为_Bool时,如果值比较等于0,则结果为0;否则,结果是1。

如果您正在使用stdbool.h,那么bool(这是一个定义为_Bool的预处理器宏)因此必须只有0或1,您的tweedledeetweedledum函数无法返回该范围之外的值,并且对它们使用按位运算应该可以达到预期效果。

但是,如果tweedledeetweedledum使用的某些其他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语句的条件,则可能根本不执行这两个函数中的一个。如果不是这样,那么最好将结果保存在两个变量中,然后直接对结果变量进行逻辑运算。