布尔运算符++和 –
今天,在编写一些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");
它来自整数值作为布尔值的历史。
如果x
是一个int
,但是我将它作为if(x)...
的布尔值来使用,那么递增将意味着无论它在操作之前的真值如何,在它之后它将具有真值(禁止溢出)。
然而,仅仅预测x
的真值的结果是不可能的,因为它可能导致false
(如果积分值为1)或true
(如果积分值是其他值 – 特别是包括0 [ false
]和2或更多[ true
])。
所以,作为一个简短的++
工作,并没有。
在bools上允许++
与此兼容,但是在标准中不再使用它。
这假设我只使用x
作为布尔值,这意味着溢出不会发生,直到我做了++
往往足以导致它自己的溢出。 即使使用chartypes和CHAR_BITS
类似5的东西,这是32倍之前,这不再工作(这仍然是足够的论据,这是一个不好的做法,我不是捍卫的做法,只是解释为什么它的作品)对于一个32位的int
我们当然必须使用++
2 ^ 32次之前,这是一个问题。 使用--
虽然只会导致false
如果我开始使用值为1为true
,或从0开始,使用++
之前精确一次。
如果我们从低于0的数值开始,这是不同的。事实上,在这种情况下,我们可能希望++
最终导致false
值,例如:
int x = -5; while(++x) doSomething(x);
但是,这个例子将x
视为除了条件之外的int
,所以它相当于:
int x = -5; while(++x != 0) doSomething(x);
这与仅将x
用作布尔值不同。
ANSI ISO IEC 14882 2003(c ++ 03):
5.2.6-2
后缀的操作数 – 类似于后缀++操作符递减,除了操作数的types不是booltypes。 [注:前缀增加和减less,见5.3.2。 ]
不出所料
5.3.2-2
前缀的操作数 – 通过减1来修改。操作数的types不能是booltypes。 对前缀操作数的要求 – 及其结果的属性与前缀++的相同。 [注:后缀增量和减量,见5.2.6。 ]
5.6.2-1和5.3.2-1也提到++对于bools应该是真的,附录D-1说在++上bools已经被弃用了。
由于历史原因,这是支持。 但是请注意…不build议使用带有++运算符的bool型操作数,请参见C ++标准(n3092)中的第5.3.2节。
5.3.2递增和递减[expr.pre.incr]
- 前缀++的操作数是通过加1来修改的,如果是bool(这个用法已被废弃),则设置为true。 操作数应该是一个可修改的左值。 操作数的types应为算术types或指向完全定义的对象types的指针。 结果是更新的操作数; 它是一个左值,如果操作数是位域,则它是一个位域。 如果x不是booltypes,则expression式++ x等价于x + = 1 [注意:有关转换的信息,请参见加法(5.7)和赋值运算符(5.17)的讨论。 – 注意]
- 前缀的操作数 – 通过减1来修改。操作数的types不能是booltypes。 对前缀操作数的要求 – 及其结果的属性与前缀++的相同。
- 用旧的标准(C ++ 98),这不是一个错误。
- 随着新标准的增加,一个布尔值被弃用。 (C ++ 11)
- 你可以在布尔值上使用增量,直到C ++ 17。