布尔运算符 ++和 -
今天,在编写一些 Visual C++ 代码时,我遇到了一些令我惊讶的事情。看来 C++ 支持 bool 的 ++(增量),但不支持 --(减量)。这只是一个随机决定,还是背后有某种原因?
这编译:
static HMODULE hMod = NULL;
static bool once = false;
if (!once++)
hMod = LoadLibrary("xxx");
这不:
static HMODULE hMod = NULL;
static bool once = true;
if (once--)
hMod = LoadLibrary("xxx");
Today while writing some Visual C++ code I have come across something which has surprised me. It seems C++ supports ++ (increment) for bool, but not -- (decrement). It this just a random decision, or there is some reason behind this?
This compiles:
static HMODULE hMod = NULL;
static bool once = false;
if (!once++)
hMod = LoadLibrary("xxx");
This does not:
static HMODULE hMod = NULL;
static bool once = true;
if (once--)
hMod = LoadLibrary("xxx");
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
它来自使用整数值作为布尔值的历史。
如果 x 是 int,但我按照
if(x)...
将其用作布尔值,那么递增将意味着无论它在操作之前的真值,在其之后将有一个真值true
(除非溢出)。但是,仅了解
x
的真值,就不可能预测--
的结果,因为它可能会导致false
(如果整数值为 1) 或true
(如果整数值为其他值 - 特别是这包括 0 [false
] 和 2 或更多 [true
>])。因此,作为简写
++
有效,而--
则无效。为了与此兼容,布尔值上允许使用
++
,但标准中不推荐使用它,并且在 C++17 中将其删除。这假设我仅使用
x
作为布尔值,这意味着溢出不会发生,直到我足够频繁地执行++
以导致其本身的溢出。即使使用 char 作为所使用的类型和CHAR_BITS
诸如 5 之类的低值,在这不再起作用之前,这已经是 32 次了(这仍然是一个不好的做法,我并不是在捍卫对于 32 位int
来说,我们当然必须使用++
2^32 次,然后才会出现问题。对于--
,如果我以true
的值为 1 开始,或者以 0 开始并使用,则只会导致
恰好之前有过一次。false
>++如果我们从比 0 稍低一点的值开始,情况就会有所不同。事实上,在这种情况下,我们可能希望
++
最终得到false
值,例如如:但是,此示例将除条件之外的所有地方的
x
视为int
,因此它相当于:这与仅使用
x
不同作为布尔值。It comes from the history of using integer values as booleans.
If
x
is anint
, but I am using it as a boolean as perif(x)...
then incrementing will mean that whatever its truth value before the operation, it will have a truth-value oftrue
after it (barring overflow).However, it's impossible to predict the result of
--
given knowledge only of the truth value ofx
, as it could result infalse
(if the integral value is 1) ortrue
(if the integral value is anything else - notably this includes 0 [false
] and 2 or more [true
]).So as a short-hand
++
worked, and--
didn't.++
is allowed on bools for compatibility with this, but its use is deprecated in the standard and it was removed in C++17.This assumes that I only use
x
as an boolean, meaning that overflow can't happen until I've done++
often enough to cause an overflow on it's own. Even with char as the type used andCHAR_BITS
something low like 5, that's 32 times before this doesn't work any more (that's still argument enough for it being a bad practice, I'm not defending the practice, just explaining why it works) for a 32-bitint
we of course would have to use++
2^32 times before this is an issue. With--
though it will only result infalse
if I started with a value of 1 fortrue
, or started with 0 and used++
precisely once before.This is different if we start with a value that is just a few below 0. Indeed, in such a case we might want
++
to result in thefalse
value eventually such as in:However, this example treats
x
as anint
everywhere except the conditional, so it's equivalent to:Which is different to only using
x
as a boolean.ANSI ISO IEC 14882 2003 (c++03):
5.2.6-2
不出所料......
5.3.2-2
5.6.2-1 和 5.3.2-1 还提到,布尔值的 ++ 应该为真,而附件 D-1 表示布尔值的 ++ 已弃用。
ANSI ISO IEC 14882 2003 (c++03):
5.2.6-2
And unsurprisingly...
5.3.2-2
Also the 5.6.2-1 and 5.3.2-1 mention that ++ for bools shall be true and Annex D-1 says that ++ on bools in deprecated.
由于历史原因,这一点得到了支持。但请注意...
不推荐使用带有 ++ 运算符的 bool 类型操作数,请参阅 C++ 标准 (n3092) 中的第 5.3.2 节
5.3.2 递增和递减 [expr.pre.incr]
添加 1,或者如果是则设置为 true
bool(不推荐使用此用法)。这
操作数应是可修改的左值。
操作数的类型应为
算术类型或指向 a 的指针
完全定义的对象类型。这
result 是更新后的操作数;这是
一个左值,并且它是一个位域,如果
操作数是一个位域。如果 x 是
不是 bool 类型,表达式 ++x
等价于 x+=1 [ 注意:参见
加法(5.7)和的讨论
赋值运算符 (5.17)
有关转换的信息。 ——尾注
]
通过减去 1。操作数应
不是 bool 类型。要求
在前缀 -- 的操作数上
其结果的属性是
其他方面与前缀相同
++。
Due to historical reasons this was supported. But note that ...
The use of an operand of type bool with the ++ operator is deprecated see Section 5.3.2 in the C++ Standard(n3092)
5.3.2 Increment and decrement [expr.pre.incr]
by adding 1, or set to true if it is
bool (this use is deprecated). The
operand shall be a modifiable lvalue.
The type of the operand shall be an
arithmetic type or a pointer to a
completely-defined object type. The
result is the updated operand; it is
an lvalue, and it is a bit-field if
the operand is a bit-field. If x is
not of type bool, the expression ++x
is equivalent to x+=1 [ Note: see the
discussions of addition (5.7) and
assignment operators (5.17) for
information on conversions. —end note
]
by subtracting 1. The operand shall
not be of type bool. The requirements
on the operand of prefix -- and the
properties of its result are
otherwise the same as those of prefix
++.