bool 与非布尔运算符的行为

发布于 2024-08-02 03:54:56 字数 406 浏览 8 评论 0原文

我真正想要的是 ||= 运算符。

old_value = old_value || possible_new_value;
old_value ||= possible_new_value;

第二行是编译器错误(c++ 没有 ||= 运算符)。

那么我的其他选择是什么?

old_value += possible_new_value;
old_value |= possible_new_value;

当我讨论这个主题时, bool 与其他非布尔运算符的行为如何?

-
-=
&
&=
...

我可以凭经验验证这些,但我最感兴趣的是标准的内容。

What I really want is a ||= operator.

old_value = old_value || possible_new_value;
old_value ||= possible_new_value;

The second line is a compiler error (c++ doesn't have a ||= operator).

So what are my other options?

old_value += possible_new_value;
old_value |= possible_new_value;

While I'm on the subject how does bool behave with other non-boolean operators?

-
-=
&
&=
...

I can verify these empirically, but I'm most interested in what the standard says.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

久夏青 2024-08-09 03:54:56

根据 4.7(积分转换)第 4 段,“如果目标类型为 bool,请参阅 4.12。如果源类型为 bool,则值 false< /code> 被转换为 0,值 true 被转换为 1。” 在 4.12 中,“算术、枚举、指针或指向成员类型的指针的右值可以转换为 bool 类型的右值。零值、空指针值或空成员指针值将被转换到 false;任何其他值都会转换为 true。”

在不允许使用 bool 操作数但允许使用整型操作数的上下文中,bool 将转换为整型。 当整数结果存储在 bool 变量中时,它将被转换为 bool

因此,您将能够使用 + 和 * 作为布尔值或和与,并且可以使用 | 和& 还。 你无法将它们混合在一起,如 (bool1 + bool2) & 如果所有三个变量都为 true,bool3 将产生 false。 ((1 + 1) & 1 是 2 & 1,即 0 或 false。)

记住 | 和|| 即使在这里也不一样。 | 将评估两边,然后评估按位或。 || 将评估第一个操作数,然后仅当该操作数为 false 时才会评估第二个操作数。

我不打算在这里讨论风格问题,但如果我做了类似的事情,我一定会发表评论,以便人们知道我在做什么以及为什么。

According to 4.7 (Integral conversions), paragraph 4, "If the destination type is bool, see 4.12. If the source type is bool, the value false is converted to zero and the value true is converted to one." In 4.12, "An rvalue of arithmetic, enumeration, pointer, or pointer to member type can be converted to an rvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true."

In a context where bool operands are not allowed but integral operands are, the bool will be converted to an integral type. When the integer result is stored in a bool variable, it will be converted to bool.

Therefore, you will be able to use + and * as boolean or and and, and you can use | and & also. You can't get away with mixing them, as (bool1 + bool2) & bool3 will yield false if all three variables are true. ((1 + 1) & 1 is 2 & 1, which is 0, or false.)

Remember that | and || don't work identically even here. | will evaluate both sides, and then evaluate the bitwise or. || will evaluate the first operand, then only if that was false will evaluate the second.

I'm not going to discuss the stylistic issues here, but if I did anything like that I'd be sure to comment it so people knew what I was doing and why.

潜移默化 2024-08-09 03:54:56

标准规定:

4.5-4“整体促销”

bool 类型的右值可以是
转换为 int 类型的右值,
false 变为零且 true
成为一体。

5.17-7“赋值运算符”

表达式的行为
形式 E1 op= E2 相当于 E1 =
E1 op E2,除了评估 E1
只有一次。 在+=和-=中,E1应
要么具有算术类型,要么是
指向可能 cv 限定的指针
完全定义的对象类型。 在所有
其他情况,E1应有算术
类型。

4.12-1“布尔转换”

算术、枚举的右值,
指针,或指向成员类型的指针可以
转换为类型的右值
布尔。 零值,空指针
值,或空成员指针值为
转换为假; 任何其他值是
转换为 true。

因此,这意味着

b1 += b2

其中 b1 和 b2 为布尔值将相当于

b1 = b1 + b2

And b1 和 b2 将提升为 0/1 整数,然后根据除 0 之外的任何内容均为 true 的规则转换回布尔值。

因此,根据标准,真值表

            true   false
true     true   true
false    true   false

+= 实际上与 ||= 一样工作。 然而,这可能会让其他程序员感到困惑,所以我仍然会避免它。

The standard sayeth:

4.5-4 "Integral Promotions"

An rvalue of type bool can be
converted to an rvalue of type int,
with false becoming zero and true
becoming one.

5.17-7 "Assignment Operators"

The behavior of an expression of the
form E1 op= E2 is equivalent to E1 =
E1 op E2 except that E1 is evaluated
only once. In += and -=, E1 shall
either have arithmetic type or be a
pointer to a possibly cvqualified
completely defined object type. In all
other cases, E1 shall have arithmetic
type.

4.12-1 "Boolean Conversions"

An rvalue of arithmetic, enumeration,
pointer, or pointer to member type can
be converted to an rvalue of type
bool. A zero value, null pointer
value, or null member pointer value is
converted to false; any other value is
converted to true.

So this means that

b1 += b2

Where b1 and b2 are boolean will be equivalent to

b1 = b1 + b2

And b1 and b2 will be promoted to 0/1 integers, and then converted back to boolean on the rule that anything other than 0 is true.

So the truth table is

            true   false
true     true   true
false    true   false

so += does in fact work as ||= according to the standard. However, this will probably be confusing other programmers, so I would avoid it still.

薯片软お妹 2024-08-09 03:54:56

你可以只使用三元运算符吗?

旧值 = !旧值? 可能的新值:旧值;

Could you just use the ternary operator?

old_value = !old_value ? possible_new_value : old_value;

我要还你自由 2024-08-09 03:54:56

不要将 |=&= 与布尔值一起使用。 它们可能在大多数时间都有效,但仍然是错误的。 通常 bool 类型只是美化的 int 或 char。 在我使用过的旧代码中,BOOL 只是类型定义为 int 或 char。 在这些情况下,如果以某种方式对位进行了操作(例如,1&2 为 0(假)),您可能会得到错误的答案。 我不确定,但我认为按位运算符的结果将是一个 int,即使对于 bool 也是如此。

Don't use |= and &= with bools. They may work most of the time, but it is still wrong. Usually the bool type is just a glorified int or char. In older code that I've worked with, BOOL is just typedef'd to int or char. In these cases, you can get the wrong answer if somehow the bits have been manipulated (For example, 1&2 is 0 (false)). And I'm not sure, but I think the result of bitwise operators is going to be an int, even for bools.

凉宸 2024-08-09 03:54:56
if (!old_value)
    old_value = possible_new_value;

这与原始条件直接等效。 它可能会生成更简单的代码,因为它不会总是分配给 old_value - 但我不希望在大型程序中轻松测量性能差异。

if (!old_value)
    old_value = possible_new_value;

This is a direct equivalent of the original condition. It might generate simpler code since it won't always assign to old_value - but I wouldn't expect the performance difference to be easily measurable in a big program.

是你 2024-08-09 03:54:56

一个区别是逻辑运算符(如 ||)保证计算顺序并提供短路,而按位运算符和算术运算符则不能。

我相信编译器将通过应用运算符将​​布尔值转换为数值 (0, 1) 并转换回来来处理非逻辑运算符。 这些转换由标准严格定义,例如:

算术、枚举、指针或指向成员类型的指针的右值可以转换为 bool 类型的右值。 零值、空指针值或空成员指针值将转换为 false,任何其他值都会转换为 true。

One difference is that the logical operators such as || guarantee the order of evaluation and provide short-circuiting, where the bit-wise and arithmetic operators do not.

I believe the compiler will treat the non-logical operators by converting the bools to numeric values (0, 1) applying the operator and converting back. These conversions are strictly defined by the standard, e.g.:

An rvalue of arithmetic, enumeration, pointer, or pointer to member type can be converted to an rvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false any other value is converted to true.

随风而去 2024-08-09 03:54:56

令人讨厌的宏黑客:

#define UPDATE(x) x = x

UPDATE(old_value) || possible_new_value;

但我根本不推荐这样做。 由于多种原因,这样的宏是一个非常糟糕的主意。

更合理的功能,但没有短路:

bool set_or(bool &old, bool value) {
  return (old = old || value);
}

...

bool v = false;
set_or(v, true);

Nasty macro hackery:

#define UPDATE(x) x = x

UPDATE(old_value) || possible_new_value;

But I don't recommend this at all. Macros like this are a very bad idea for several reasons.

A more sane function, but without the short-circuiting:

bool set_or(bool &old, bool value) {
  return (old = old || value);
}

...

bool v = false;
set_or(v, true);
仙气飘飘 2024-08-09 03:54:56

我相信标准将 true 和 false 明确定义为 1 和 0,因此您可以安全地对 bool 值使用按位运算符。 在另一个上下文中可能被隐式视为布尔值的其他类型应该显式转换,以使其可靠地工作。

我见过微软的编译器每次执行此操作时都会生成一个丑陋的警告,因为它认为将 int 结果隐式转换回 bool 存在危险。

I believe the standard explicitly defines true and false as 1 and 0, so you can safely use bitwise operators on bool values. Other types that might be implicitly treated as bools in another context should be explicitly converted for this to work reliably.

I've seen Microsoft's compiler generate an ugly warning each time you do this, because it thinks there's a danger in implicitly converting the int result back to bool.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文