bool运算符++和 -

Sum*_*uma 101 c++ boolean increment

今天在编写一些Visual C++代码时,我遇到了令我惊讶的事情.似乎C++支持bool的++(增量),但不支持 - (减量).这只是一个随机决定,还是有一些原因呢?

这编译:

static HMODULE hMod = NULL;
static bool once = false;
if (!once++)
    hMod = LoadLibrary("xxx");
Run Code Online (Sandbox Code Playgroud)

这不是:

static HMODULE hMod = NULL;
static bool once = true;
if (once--)
    hMod = LoadLibrary("xxx");
Run Code Online (Sandbox Code Playgroud)

Jon*_*nna 89

它来自使用整数值作为布尔值的历史.

如果x是一个int,但我使用它作为布尔值,if(x)...那么递增将意味着无论它在操作之前的真值,它将具有它true之后的真值(禁止溢出).

然而,不可能--仅仅预测真实值的给定知识的结果x,因为它可能导致false(如果积分值为1)或true(如果积分值是其他任何东西 - 特别是这包括0 [ false]和2或更多[ true]).

所以作为一个简单的++工作,并--没有.

++ 允许在bools上与此兼容,但在标准中不推荐使用它.


这假定我使用x作为一个布尔值,这意味着不可能发生溢出,直到我做++往往不足以引起它自己的溢出.即使使用char作为所使用的类型和CHAR_BITS类似5的低点,在此之前的32次不再起作用(这仍然是足够的论据,因为它是一种不好的做法,我不是在捍卫这种做法,只是解释它为什么有效)对于32位,int我们当然必须使用++2 ^ 32次才能解决这个问题.随着--虽然它只会造成false当我开始为值1 true,或开始用0和使用++前,正是一次.

如果我们从一个低于0的值开始,这是不同的.实际上,在这种情况下,我们可能希望最终++产生false值,例如:

int x = -5;
while(++x)
  doSomething(x);
Run Code Online (Sandbox Code Playgroud)

然而,这个例子把x作为一个int无处不在,除了有条件的,所以它等同于:

int x = -5;
while(++x != 0)
  doSomething(x);
Run Code Online (Sandbox Code Playgroud)

这与仅使用x布尔值不同.

  • 但如果x为-1(在VB等某些平台上为TRUE),则++ x将为FALSE. (8认同)
  • @James,在C和C++中,当我说("禁止溢出")时,我会想到这种情况.实际上在VB中,任何非零都有真值TRUE(就像在C中一样),但是由于真正的布尔运算,它们有-1而不是1,因为NOT(TRUE)是FALSE,NOT(FALSE)是TRUE,x OR TRUE为TRUE,x OR FALSE为x,x AND FALSE为FALSE,x AND TRUE为x等,使用相同的运算符进行布尔运算和逐位运算(因为VB假设为二进制补码,因此-1为全1位).但是,如果编码器没有捕获到2(真)和4(真)导致0(假),这可能会导致VB中的一些奇怪的错误. (4认同)
  • @JonHanna:ANSI C89是第一个C标准.ANSI C委员会发明了`<limits.h>`标题和`CHAR_BIT`宏.在此之前,我认为理论上可能是`char`比8位窄的实现,但据我所知,没有.特别是,K&R1(1978年出版)列出了4个示例实现,所有这些实现都有8位或9位`char`. (2认同)

Nor*_*ame 30

ANSI ISO IEC 14882 2003(c ++ 03):

5.2.6-2

后缀的操作数 - 与postfix ++运算符类似地递减,除了操作数不应该是bool类型.[注意:对于前缀增量和减量,请参见5.3.2.]

不出所料......

5.3.2-2

前缀的操作数 - 通过减1来修改.操作数不应该是bool类型.对前缀的操作数的要求 - 以及其结果的属性在其他方面与前缀++相同.[注意:对于后缀增量和减量,请参见5.2.6.]

5.6.2-1和5.3.2-1也提到了用于bools的++应该是真的,附件D-1表示对bools的++已经弃用了.

  • @BlueRaja:见Jon Hanna的回答. (3认同)

Abh*_*hay 9

由于历史原因,这得到了支持.但请注意...... 不推荐使用bool类型的操作数和++运算符,请参阅C++标准中的第5.3.2节(n3092)

5.3.2递增和递减[expr.pre.incr]

  • 前缀++的操作数通过添加1来修改,或者如果它是bool则设置为true(不推荐使用此用法).操作数应是可修改的左值.操作数的类型应为算术类型或指向完全定义的对象类型的指针.结果是更新的操作数; 它是一个左值,如果操作数是一个位域,它是一个位域.如果x不是bool类型,则表达式++ x等效于x + = 1 [注意:有关转换的信息,请参阅加法(5.7)和赋值运算符(5.17)的讨论. - 尾注]
  • 前缀的操作数 - 通过减1来修改.操作数不应该是bool类型.对前缀的操作数的要求 - 以及其结果的属性在其他方面与前缀++相同.