如果两个函数每个 return bool,使用按位运算符组合它们是否安全?
If two functions each return bool, is it safe to use bitwise operators to combine them?
假设我有两个可能有副作用的函数和 return 布尔值。 (使用 <stdbool.h>
中定义的 bool
,因此将 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。)
我唯一的保留意见是,我不确定 returning bool
函数是否可以安全地假定为 return 1 和 0,而不是其他替代项true
.
的值
举个例子:如果有恶人按照下面的方式实现会怎样?
bool tweedledee(MyState *pmystate)
{
return 66;
}
bool tweedledum(MyState *pmystate)
{
return 33;
}
则66 & 33
为0,66 | 33
为99。
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.
是的。您可以安全地假设这一点并使用按位运算。
从 C99 (ISO 9899:1999) 7.16.3:
The remaining three macros are suitable for use in #if
preprocessing
directives. They are:
true
which expands to the integer constant 1,
false
which expands to the integer constant 0, and
__bool_true_false_are_defined
which expands to the integer constant 1.
来自 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; otherwise, the result is 1.
如果你正在使用stdbool.h
,那么bool
(这是一个定义为_Bool
的预处理器宏)因此必须是只有 0 或 1,您的 tweedledee
和 tweedledum
函数不能 return 超出该范围的值,并且对它们使用按位运算应该可以达到您的预期。
但是,如果 tweedledee
和 tweedledum
使用的 bool
不是 _Bool
的其他类型,则所有投注均无效。
在某种程度上,您发布的示例的安全性将取决于所使用的compiler/version/platform。
使用“&”的可能更安全的实现如下所示:
bool either_tweedle = ( tweedledee(&mystate) != 0 ) & ( tweedledum(&mystate) != 0 );
这可以防止 tweedledee 或 tweedledum 将 0 或 1 以外的值推入其布尔 return 值的可能性。
'|'你提供的外壳应该是绝对安全的。
如果您将逻辑运算的结果用作 if 语句的条件,则两个函数之一可能根本不会执行。如果不是这样,那么最好将结果保存在两个变量中,然后直接对结果变量进行逻辑运算。
假设我有两个可能有副作用的函数和 return 布尔值。 (使用 <stdbool.h>
中定义的 bool
,因此将 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。)
我唯一的保留意见是,我不确定 returning bool
函数是否可以安全地假定为 return 1 和 0,而不是其他替代项true
.
举个例子:如果有恶人按照下面的方式实现会怎样?
bool tweedledee(MyState *pmystate)
{
return 66;
}
bool tweedledum(MyState *pmystate)
{
return 33;
}
则66 & 33
为0,66 | 33
为99。
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.
是的。您可以安全地假设这一点并使用按位运算。
从 C99 (ISO 9899:1999) 7.16.3:
The remaining three macros are suitable for use in
#if
preprocessing directives. They are:
true
which expands to the integer constant 1,
false
which expands to the integer constant 0, and
__bool_true_false_are_defined
which expands to the integer constant 1.
来自 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; otherwise, the result is 1.
如果你正在使用stdbool.h
,那么bool
(这是一个定义为_Bool
的预处理器宏)因此必须是只有 0 或 1,您的 tweedledee
和 tweedledum
函数不能 return 超出该范围的值,并且对它们使用按位运算应该可以达到您的预期。
但是,如果 tweedledee
和 tweedledum
使用的 bool
不是 _Bool
的其他类型,则所有投注均无效。
在某种程度上,您发布的示例的安全性将取决于所使用的compiler/version/platform。
使用“&”的可能更安全的实现如下所示:
bool either_tweedle = ( tweedledee(&mystate) != 0 ) & ( tweedledum(&mystate) != 0 );
这可以防止 tweedledee 或 tweedledum 将 0 或 1 以外的值推入其布尔 return 值的可能性。
'|'你提供的外壳应该是绝对安全的。
如果您将逻辑运算的结果用作 if 语句的条件,则两个函数之一可能根本不会执行。如果不是这样,那么最好将结果保存在两个变量中,然后直接对结果变量进行逻辑运算。