简体   繁体   English

如果两个函数都返回布尔值,使用按位运算符将它们组合起来是否安全?

[英]If two functions each return bool, is it safe to use bitwise operators to combine them?

Suppose I have two functions which may have side effects, and return boolean values. 假设我有两个可能会有副作用的函数,并返回布尔值。 (with bool as defined in <stdbool.h> , so that defines bool as the _Bool type) (与bool中定义<stdbool.h>以便定义bool作为_Bool型)

bool tweedledee(MyState *pmystate);
bool tweedledum(MyState *pmystate);

Is it safe to use bitwise operators to combine them? 使用按位运算符组合它们是否安全?

bool both_tweedles = tweedledee(&mystate) & tweedledum(&mystate);

or 要么

bool either_tweedle = tweedledee(&mystate) | tweedledum(&mystate);

I would traditionally use the logical operators && or || 传统上,我会使用逻辑运算符&&|| ; ; I'm working on a project where my team members are using the bitwise operators, since the functions may have side effects, and we want both function calls to occur. 我正在一个项目中,我的团队成员正在使用按位运算符,因为这些函数可能会产生副作用,并且我们希望两个函数都发生。 (The logical operators are short-circuiting .) (逻辑运算符正在短路 。)

My only reservation is that I'm not sure whether a function returning bool can safely be assumed to return 1 and 0, rather than something else as an alternate value for true . 我唯一的保留意见是,我不确定是否可以安全地将返回bool的函数假定为返回1和0,而不是将其他值作为true的替代值。


Just as an example: what if someone evil implemented them as follows? 举个例子:如果邪恶的人按如下方式实施了该怎么办?

bool tweedledee(MyState *pmystate)
{
   return 66;
}

bool tweedledum(MyState *pmystate)
{
   return 33;
}

then 66 & 33 is 0, and 66 | 33 那么66 & 33是0,而66 | 33 66 | 33 is 99. 66 | 33是99。

From section 6.3.1.2/1 of the C99 standard: 根据C99标准的6.3.1.2/1部分:

When any scalar value is converted to _Bool, the result is 0 if the value compares equal to 0; 当任何标量值转换为_Bool时,如果该值比较等于0,则结果为0;否则,结果为0。 otherwise, the result is 1. 否则,结果为1。

If you're using stdbool.h , then bool (which is a preprocessor macro defined to be _Bool ) therefore must be only 0 or 1, your tweedledee and tweedledum functions cannot return values outside of that range, and using bitwise operations on them should do what you expect. 如果您使用的是stdbool.h ,则bool (这是定义为_Bool的预处理器宏)因此必须仅为0或1,您的tweedledeetweedledum函数不能返回该范围之外的值,并且应对它们使用按位运算做到您的期望。

If, however, tweedledee and tweedledum are using some other bool type that isn't _Bool , then all bets are off. 但是,如果tweedledeetweedledum使用的不是_Bool其他bool类型,则所有下注均无效。

To some extent, the safety of the sample that you posted will depend on the compiler/version/platform in use. 在某种程度上,您发布的示例的安全性将取决于使用的编译器/版本/平台。

A potentially safer implementation for the use of '&' would be something like the following: 使用'&'可能更安全的实现如下所示:

bool either_tweedle = ( tweedledee(&mystate) != 0 ) & ( tweedledum(&mystate) != 0 );

This defends against the possibility of either tweedledee or tweedledum shoving a value other than 0 or 1 into their bool return value. 这可以防止tweedledee或tweedledum将0或1以外的值推入其布尔返回值的可能性。

The '|' “ |” case you provided should be perfectly safe. 您提供的保护套应该绝对安全。

I'm not sure whether a function returning bool can safely be assumed to return 1 and 0, rather than something else as an alternate value for true. 我不确定是否可以安全地假设返回布尔值的函数返回1和0,而不是将其他值作为true的替代值。

Yes. 是。 You can safely assume this and use bitwise operations. 您可以放心地假设并使用按位运算。

From C99 (ISO 9899:1999) 7.16.3: 根据C99(ISO 9899:1999)7.16.3:

The remaining three macros are suitable for use in #if preprocessing directives. 其余三个宏适用于#if预处理指令。 They are: 他们是:

true which expands to the integer constant 1, true ,它扩展为整数常量1,

false which expands to the integer constant 0, and false ,它扩展为整数常量0,并且

__bool_true_false_are_defined which expands to the integer constant 1. __bool_true_false_are_defined扩展为整数常量1。

If you are using the result of the logical operation as the condition of an if-statement, it is possible that one of the both functions will not be executed at all. 如果将逻辑运算的结果用作if语句的条件,则两个功能之一可能根本不会执行。 If this is not intended, then you'd better save the results in two variables and then do logical operation directly on the result variables. 如果不希望这样做,则最好将结果保存在两个变量中,然后直接对结果变量进行逻辑运算。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM