web-dev-qa-db-ja.com

bool演算子++および-

今日、いくつかの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");
100
Suma

これは、ブール値として整数値を使用した歴史から来ています。

xintであるが、if(x)...に従ってブール値として使用している場合、インクリメントすると、操作前の真理値に関係なく、trueの真理値を持つことになります(オーバーフローを除く) )。

ただし、x(積分値が1の場合)またはfalse(積分値が他の値の場合-特に)になる可能性があるため、trueの真理値のみを知っている--の結果を予測することは不可能です。これには、0 [false]と2つ以上の[true]が含まれます)。

したがって、ショートハンド++は機能し、--は機能しませんでした。

++は、これとの互換性のためにブールで許可されていますが、その使用は標準では廃止されています。


これは、I onlyxをブール値として使用することを前提としています。つまり、オーバーフローを引き起こすのに十分な頻度で++を完了するまで、オーバーフローは発生しません。使用される型としてcharがあり、CHAR_BITSが5のように低い場合でも、これが機能しなくなる前に32倍になります(これは悪い習慣であるために十分な議論です。 32ビットのintの場合、これが問題になる前に++を2 ^ 32回使用する必要があります。 --では、falseの値を1で始めた場合、または0で始めて++を1回だけ使用した場合にのみtrueになります。

0を少し下回る値で開始する場合、これは異なります。実際、このような場合、++の結果としてfalse値が最終的に次のようになる場合があります。

int x = -5;
while(++x)
  doSomething(x);

ただし、この例では、条件を除くすべての場所でxintとして処理するため、次と同等です。

int x = -5;
while(++x != 0)
  doSomething(x);

これは、xをブール値としてのみ使用することとは異なります。

88
Jon Hanna

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

5.2.6-2

Postfix-のオペランドは、postfix ++演算子と同様にデクリメントされますが、オペランドはbool型ではありません。 [注:プレフィックスのインクリメントとデクリメントについては、5.3.2を参照してください。 ]

そして当然のことながら...

5.3.2-2

プレフィックス-のオペランドは、1を減算することにより変更されます。オペランドはブール型であってはなりません。それ以外の場合、prefixのオペランドの要件と結果のプロパティは、prefix ++の要件と同じです。 [注:後置インクリメントとデクリメントについては、5.2.6を参照してください。 ]

また、5.6.2-1および5.3.2-1では、boolの++が真であると言及されており、Annex D-1では、boolの++は廃止される予定です。

30

歴史的な理由により、これはサポートされていました。ただし、...++演算子でのbool型のオペランドの使用は推奨されないことに注意してください。C++標準のセクション5.3.2を参照してください(n3092)

5.3.2増分および減分[expr.pre.incr]

  • プレフィックス++のオペランドは、1を追加することによって変更されます。ブール値の場合はtrueに設定されます(この使用は非推奨です)。オペランドは変更可能な左辺値でなければなりません。オペランドの型は、算術型または完全に定義されたオブジェクト型へのポインターでなければなりません。結果は更新されたオペランドです。これは左辺値であり、オペランドがビットフィールドの場合はビットフィールドです。 xがbool型でない場合、式++ xはx + = 1と同等です[注:変換については、加算(5.7)および代入演算子(5.17)の説明を参照してください。 —注を終了]
  • プレフィックス-のオペランドは、1を減算することにより変更されます。オペランドはブール型であってはなりません。それ以外の場合、prefixのオペランドの要件と結果のプロパティは、prefix ++の要件と同じです。
9
Abhay
  • 古い標準(C++ 98)では、エラーではありません。
  • 新しい標準の増加に伴い、ブール値は非推奨になりました。 (C++ 11)
  • C++ 17までブール値に増分を使用できます。
2
mustafagonul