2009-06-19 5 views
2

C++標準のセクション4.12で述べている、なぜC++で算術値または列挙値を暗黙的にブール値に変換できますか?

算術、列挙、ポインタ、またはポインタの右辺値メンバー型には、bool型の右辺値に変換することができます。ゼロ値、ヌルポインタ値、またはヌルメンバポインタ値はfalseに変換され、他の値はtrueに変換されます。次のコードが有効であることを意味し

は、

if(5) 
    std::cout << "WOW!"; 

それは構文的に有効ですが、意味的にはどんな意味がありません。私の質問は、なぜC++がそのような変なことを許しているのかということです。 AFAIK、それは混乱よりもむしろ有利ではありません。

+5

これは単なるトローリングです。本当の質問ではありません。 –

+3

ポスターはまともな歴史を持っていますが、これが本物ではないと思われる理由は何ですか? – AakashM

+3

C(またはアセンブリ言語)で育った世界中のプログラマーの大群には意味的な意味があります。 –

答えて

21

私はそれが歴史だし、A Cがコンセプトのようなブール値を評価するために使用方法の積でを考える...

Cが金属にboolean型を持つように使用し、「ダウンではなかったです'Cのポインター、ポインター、数値型などは暗黙的にfalseに設定されていました。

「nothing/zero == false」と「何か他== true」と考えると、実際には意味があります。

+7

そして、Cが0 == falseを使用する理由は0 == trueではなく、実際にはプロセッサにデータ型が全くないことです。異なるサイズのレジスタ(あなたが運が良ければ)です。ハードウェアでサポートされている 'ブール値'演算は、レジスタ内で0または0以外の値になります。 Cはちょうどそれをプログラマに見えるようにしました。 Cは高レベルのアセンブリ言語と考えることができ、理にかなっています。 –

7

実際には、C/Python/Perl/BASIC非ゼロの整数/ポインタ値 を含む多くの言語で、常に0が偽とみなされます。

これは多くのプログラミング言語で知られている慣例なので、理由はありません。理由はありません。これはC++に含まれていませんか?

なぜJavaではこれはそうではないのですか?

+3

おそらく、プログラマが論理条件に明示的になり、コードをより読みやすくすることを強いるでしょう。 –

3

またC.

ノートの生成物からだ、これらは、(論理的に計算しない場合)と等価である:(のx * yを場合

(X & &のy || z)の場合

+ Z)

TI99/4A BASICを持っているとNOR OR演算をするので、*と+は、二重の義務をしなければならなかったしなかったので(私はこれを知っている、とTI99/4aがBASICで、真偽値はC.

のように働いていました
+3

そうではありません。 x == 1かつy == -1ならば、x || yは真ですが、x + yは偽です。 –

1

これは、特定のハードウェア制限の成果物です。

「int」、「short」、「bool」などの用語は、 al。実行時には1ワード(8ビット)値、2ワード(16ビット)値、4ワード(32ビット)値などのように、実際には意味の異なる意味を持ちます。

だから、本当の質問は「なぜC++はブール値として5を除いているのですか」ではなく「なぜCですか?」ということです。そして答えは、メモリアラインメントのために、どこでも単一のビットを格納することができなかったため、コンパイラはただ単語全体を使用しました。 C++に指定された "bool"型があるという事実は、ちょっとした手を振るだけです。

0

これは推測ですが、私はそれがC言語がミニマリスト言語として設計されているためですと信じています。

最初に、ブール評価と算術評価は非常に似ているので、実際にはCパーサーで結合されているため、パーサの全体的なサイズが小さくなります。

第2に、アセンブリでゼロ以外の結果をテストするには、レジスタをゼロ値でテストし、trueの場合はステートメントの 'else'部分にジャンプする単一のオペコードを使用します。値がゼロ以外の場合、ステートメントの 'if-true'部分に自然に実行が移ります。

0

従来、Cは比較的堅牢ではなく簡素で効率的に設計された比較的Weakly Typed languageです。パスカルなどの言語はより厳密に型付けされています。列挙型、ポインタ型、int型、bool型は、式の中でランダムに混合したり、一致させることはできません。

C(と多くのC++)プログラマはこのような背景で育ってきた、そしてあなたは、このような慣用的なコードしばしば表示されます:

while (1) 
    dosomething(); // repeats forever 

..か...個人的に

char * pointer; 

if (pointer) // tests pointer for being != 0, which equals NULL. 
    fred = *pointer; 

をC/C++を20年以上使用しているにもかかわらず、この2番目の慣用句は、(NULL == 0)、(0 == FALSE) 。

2

私はその理由が歴史だと思います。病気形成

enum class X { A, B, C }; 
if(X::B) { ... } 

それは、次のコードを作り、その次のC++のバージョン(C++ 0X、C++ 1X)は暗黙的に整数に変換することが許可されていないスコープの列挙を導入注意する価値があるかもしれませんしかし、列挙子の実際の値が二次的なものに過ぎないので、列挙のために数値に暗黙的な変換を許可することは当然ですほとんどの時間、私は信じています。スコープ列挙キャストこれは、列挙の必要なCとの互換性は、これまで許可していませんでしたいくつかの型の安全性を追加し

if(static_cast<bool>(X::B)) { ... } 

が必要になります(私は普通の列挙に禁じられている場合、これは多くのコードを壊す推測します)。

0

私は正確な引用を見つけることができませんが、アセンブリ言語のすべてのパワーと柔軟性と安全性とアセンブリ言語の使い易さを組み合わせたと常に言われました。

通常、プロセッサにはブール型、整数型、ptr型はありません。それらはすべてメモリまたはレジスタ内の単なる数字です。

some_obj * thingy; 
if (thingy) ... 

「ブツが存在する」または「初期化されている」表現するために、自然と簡潔な方法のように思える:

は個人的に私はいつもイディオムを言っていました。しかし、その後、私はアセンブリ言語で多くの時間を費やしました。

私はObjective-C、Java、C#で "thingy == null"(またはnil)を使用する傾向がありますが、ハードウェアから離れている言語で何が起こっているのかが少しはっきりと感じられます。いくつかの言語では、誰かが "=="演算子をオーバーライドすることさえできます。

「if(ptr)...」という暗黙の「ブール値へのキャスト」演算子を呼び出すと考えることができます...

0

そこに良い答えがありますが、私はもう一つのことを指摘したい:あなたはboolean = numberboolean = pointerを言うことができない場合でも、それはまだif(number)またはif(pointer)構成を有していることは理にかなっています。

関連する問題