なぜC ++のブール型は++をサポートしているのに-ではないのですか?


29

なぜ演算子--はboolには存在しないのに、演算子には存在しないの++ですか?

C ++で試しましたが、質問が他の言語に当てはまるかどうかわかりません。私も知りたいです。

私は知っている、私は++ブールで演算子を使用することができます。boolをtrueに等しくします。

bool b = false;
b++;
// Now b == true.

--反対の方法で演算子を使用できないのはなぜですか?

bool b = true;
b--;
// Now b == false;

あまり便利ではありませんが、興味があります。


8
StackOverflowに関するこの質問は啓発的かもしれません。
Blrfl 14年

歴史の理由です。リンクありがとうございます。答えを書いてもらえますか?
aloisdgは、Reinstate Monica 14年

リンクだけでは良い答えが得られず、tnisの質問に別のSEサイトにあるものの複製をマークするための良いメカニズムがありません。
Blrfl 14年

1
したがって、meta.stackexchange.comなどでトピックを開く必要があります。良いリンクのためにカルマを手に入れるべきだと思います。誰かがあなたに賛成したら、元の答えの著者はカルマを手に入れるべきです。実際、元の質問にもカルマが必要です。
aloisdgは、Reinstate Monicaが14年

2
@aloisdgクロスサイトデュップは、MSOの古い問題です。リンクされた質問を追跡して、より詳細なビューを取得します。

回答:


53

Cの昔は、ブール型はありませんでした。人々はintブールデータを保存するために使用し、それはほとんど働いた。 ゼロは偽であり、他のすべては真実でした。

これint flag = 0;flag++、値を取得し、後で実行した場合に値が真になることを意味します。これは、フラグの値が何であっても機能します(多くの場合を除き、ロールオーバーしてゼロに戻りましたが、それは無視できます) -値が1のときにフラグをインクリメントすると2が得られます本当。

一部の人々は、ブール値を無条件にtrueに設定するためにこれを使用しました。私はそれが今までにイディオムになったとは確信していませんが、それはいくつかのコードで。

--値が1(それが可能性がある)以外の場合、値はまだfalseにならないため、これは決して機能しませんでした。そして、それが既に偽(0)であり、それに対してデクリメント演算子を実行した場合、偽のままではありません。

初期の段階でCからC ++にコードを移動する場合、C ++に含まれるCコードが引き続き機能できることが非常に重要でした。そのため、C ++仕様(セクション5.2.6(71ページ))では次のように書かれています:

接尾辞++を適用して得られる値は、演算子を適用する前にオペランドにあった値です。[注:得られる値は元の値のコピーです]オペランドは変更可能な左辺値でなければなりません。オペランドの型は、算術型または完全なオブジェクト型へのポインタでなければなりません。結果が記録された後、オブジェクトがtype boolである場合を除き、オブジェクトの値は1を追加して変更されます。その場合、オブジェクトはtrueに設定されます。[注:この使用は非推奨です。付録Dを参照してください。]

接尾辞のオペランド-は、接尾辞++演算子と同様にデクリメントされますが、オペランドはtypeであってはなりませんbool

これはセクション5.3.2で再び言及されています(プレフィックス演算子の場合-5.2.6はpostfixにありました)

ご覧のとおり、これは非推奨(709ページのドキュメントの付録D)であり、使用すべきではありません。

しかし、それが理由です。また、コードが表示される場合があります。しかし、それをしないでください。


5
「一部の人々は、ブール値を無条件にtrueに設定するためにこれを使用しました。」人々ではなく、それらをいまいましい愚か者と呼びましょう。
デデュプリケーター

@Deduplicator:多分それはパフォーマンスの問題だったかもしれません:変数に値をロードすることは、変数をインクリメントするよりも多くのプロセッサーサイクルを要したかもしれません。もちろん、これはおそらく現代のコンピューターでは重要ではありません。
ジョルジオ

1
@Giorgioそれはかなりありそうです。CはPDP-7命令セットに厳密に一致するように記述されており、PDP-11には他の調整があったことを思い出してください。この - 「人々はしばしば、彼らがCとUnixが最初に人気になった上で12月PDP-11が提供する自動インクリメントおよび自動デクリメントのアドレスモードを使用するために作成されたことを推測何PDP-がなかったので、これは、歴史的には不可能です。 11 Bが開発されました。しかし、PDP-7にはいくつかの「自動インクリメント」メモリセルがあり、それらを介した間接メモリ参照がセルをインクリメントするという特性がありました。」

@Deduplicator:ブール値に整数を使用するコードでは、それぞれにインクリメントされる変数...何でも...カウンター(インクリメントされた回数)とブール値(インクリメントされた、またはない)。
キーストンプソン


1

この質問の歴史的意義を理解するには、Therac-25のケースを考慮する必要があります。Therac-25は、がん患者に放射線を照射する医療機器でした。悪いプログラミングの慣行に悩まされていたため、安全性の記録が不十分でした(複数の死者が発生したため)。

http://courses.cs.vt.edu/professionalism/Therac_25/Therac_1.html

(3ページの最後に移動)

セットアップテストルーチンを通過するたびに、Class3と呼ばれる共有変数である上部コリメータの位置チェックが増加します。Class3がゼロ以外の場合、矛盾があり、処理を続行しないでください。Class3のゼロ値は、関連するパラメーターが治療と一致しており、ビームが抑制されていないことを示します。

...

マシンのセットアップ中、セットアップテストは、他のイベントが発生するのを待って再スケジュールされるため、数百回実行されます。コードでは、セットアップテストの各パスでClass3変数が1つずつ増加します。Class3変数は1バイトであるため、255の10進数の最大値のみを含めることができます。したがって、セットアップテストコードを256回通過するたびに、変数がオーバーフローし、値がゼロになります。つまり、セットアップテストを256回パスするたびに、上部コリメータはチェックされず、上部コリメータの障害は検出されません。Class3がゼロにロールオーバーした正確な瞬間にオペレーターが「設定」ボタンを押すと、露出過剰が発生しました。したがって、Chkcolは実行されず、F $ malは、上部コリメータがまだフィールドライト位置にあることを示すように設定されていませんでした。ソフトウェアは、ターゲットを配置せずに、スキャンせずに25 MeV全体をオンにしました。その結果、高濃度の電子ビームが発生し、経路にあるステンレススチールミラーによって散乱および偏向されました。

Therac-25 operator++はa と同等のものを使用しましたbool。ただし、彼らが使用したプログラミング言語はC ++ではなく、データ型はでしたbool。ただし、C ++の保証とは異なり、通常の整数型は単純に上がり続けます。それらのデータ型はと同等でしたuint8_t

C ++は、operator++このようなプログラミングに慣れている人々のために周囲を維持することにしましたが、値を増やす代わりに、trueこのようなことを防ぐために単純に設定します。

operator++(bool)廃止されることに注意してください。

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf

C ++ 14の付録D:

D.1 boolオペランドを
使用したインクリメント演算子++演算子を使用したbool型のオペランドの使用は非推奨です(5.3.2および5.2.6を参照)。


廃止される理由は説明されますが、そもそもなぜ存在するのかは説明されていません。

これは、Cでのプログラミング時にブール値をインクリメントして設定する人がいたためです。C++はCからの移行を容易にするように設計されているため、bool型でサポートしていました。私は、人々が実際にこの方法でプログラムしたときの歴史的な例を挙げようとしていました。
デビッドストーン14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.