いくつかの整数しか使用できないことはわかっていますが#define
、C99より前にCに専用のブールデータ型がなかったのはなぜですか?
これはプログラミングやロジックでよくあることですが、明示的な型や表記法がないことはわかりません。
いくつかの整数しか使用できないことはわかっていますが#define
、C99より前にCに専用のブールデータ型がなかったのはなぜですか?
これはプログラミングやロジックでよくあることですが、明示的な型や表記法がないことはわかりません。
図書館で少し時間を過ごすなら、推測する必要はありません。これは、Cの進化に関するDennisRitchieの論文から抜粋したいくつかのステートメントです。コンテキストは、デニスがケン・トンプソンの言語Bに基づいて構築されているということです。この言語は、単語アドレス指定されたマシンである非常に小さなPDP-7に実装されていました。関心が高まったため、グループは最初のPDP-11の1つを手に入れました。デニスはこう書いています、
PDP-11の出現により、Bのセマンティックモデルのいくつかの不備が明らかになりました。まず、BCPLからほとんど変更されていない、その文字処理メカニズムは不器用でした。ライブラリプロシージャを使用して、パックされた文字列を個々のセルに広げてから再パックしたり、個々の文字にアクセスして置換したりすると、バイト指向のマシン。
BおよびBCPLモデルは、ポインターを処理する際のオーバーヘッドを意味します。言語規則では、ポインターを単語の配列内のインデックスとして定義することにより、ポインターを単語インデックスとして表現するように強制しました。各ポインター参照は、ポインターからハードウェアが期待するバイトアドレスへのランタイムスケール変換を生成しました。
これらすべての理由から、文字とバイトアドレス指定に対処し、次の浮動小数点ハードウェアに備えるために、タイピングスキームが必要であるように思われました。他の問題、特に型安全性とインターフェースのチェックは、その後になるほど重要ではないように思われました。
(エンファシスマイン。)
struct
このホワイトペーパーでは、新しいポインタセマンティクスを発明し、配列を機能させ、この新しいアイデアに同意するためのデニスの苦労について説明します。型安全性の概念とブール値と整数の区別は、ずっと後になるまで重要ではなかったようです:-)
Cは、実際には高レベルのアセンブリ言語にすぎません。はい、それは制御構造などを持っていて、アセンブラが確かに必要としないタイプさえ持っていました。
しかし、この言語は数十年前に設計されました。そして、すべてのブール結果はプロセッサのステータスワードの個々のビットに到達するため、整数データ型を使用するだけで明らかに十分でした。また、型チェックを省略できるため、コンパイラの複雑さが少し軽減されます(後の言語では、制御構造にはブール値が必要ですが、Cでは0またはその他の整数値が必要です)。
CPUには「ブール型」がなく、バイトとその倍数でしか機能しないため、ブール型は利点がないため、当時は意味がありませんでした(「is0」しかチェックできない型を使用する理由)または「nullではない」)
ゼロを偽として扱い、ゼロ以外を真として扱うことは一般的でした(そして場合によってはまだそうです)。これには速記の利点があります。たとえば、代わりにwhile (remaining != 0)
を使用できますwhile (remaining)
。
一部の言語は、trueが-1であることに標準化されています。この理由は、2の補数表記(ほとんどのコンピューターが負の数を表すために使用する)では、0のビット単位ではなく-1(8ビットの2進数で11111111
は10進数の-1)であるためです。
時間の経過とともに、コンパイラー定義の定数を使用することで、多くの潜在的な混乱を防ぐことができることがわかりました。C ++を実行してからしばらく経ちますが、ゼロ以外の値でも「true」と評価されると確信しています。
整数型で十分だと思われます。0はfalseで、0以外はtrueです。
ブール値(通常)を格納するために使用するタイプは、空間と時間の間のトレードオフを具体化します。通常、int(通常は4バイト)を使用すると、(少なくとも個々の操作で)最速の結果が得られます。一方、非常に多くを使用している場合は、1バイトを使用するか、パックする方がはるかに理にかなっているため、格納する各値は1ビットのみを使用します。 1ビットの読み取りまたは書き込みは、かなりコストがかかります(そして余分なコードを使用します)。
本当に「正しい」答えは1つもなかったので、彼らは自分たちが書いているプログラムの要件に基づいて決定することをユーザーに任せました。
したがって、本当の問題は、C99でブール型が追加された理由です。私の推測では、いくつかの要因が関係しています。最初に、彼らは、プログラマーにとっての読みやすさと利便性が、可能な限り最高のパフォーマンスを提供することよりも、通常は重要であることに気づきました。第二に、コンパイラーはかなりグローバルな分析を行うようになったので、少なくとも誰かが特定のプログラムに最も適切な表現を選択しようとするコンパイラーを作成する可能性があると推測できます(実際にそうするものはわかりませんが) )。
Old Cは、ブール型を実際に「見逃している」わけではありませんでした。すべての整数型も、ブール値を格納する二重の役割を実行するのに適していると見なされていただけです。私はこれの2つの主な理由を見ることができます:
ビットアドレス指定プロセッサはまったく一般的ではなかった(そして今でもそうではない)ので、コンパイラは実際には「真のブール」型を使用してスペースを節約することはできません。ブールは少なくとも同じ大きさです。とにかく(効率的にアクセスしchar
たい場合)。
int
とにかく、式で拡張されるよりも狭い型int
-したがって、ブール演算子は引き続きint
オペランドで機能します。
..したがって、専用のブール型が実際に実用的な利点をもたらすような説得力のある十分なケースがなかったように見えます。
C言語には、ブール結果(0または1のいずれかとして定義)を生成する一連の演算子があることに注意してください-、、、、、、、、、および-したがって!
、そこ&&
にない||
のは専用のブール型のみです。!=
==
<
<=
>
>=
歴史的な理由、おそらく:
ALGOLの影響を強く受けたCPLは、ブール型である可能性が高いですが、私のgoogle-fuはこれのリファレンスを見つけるのに十分ではありませんでした。しかし、CPLは当時は野心的すぎたため、BCPLと呼ばれる簡略化されたバージョンが作成されました。これには、利用可能なハードウェアに実際に実装できるという利点がありました。
BCPLには単一のタイプ(「単語」)しかありませんでした。これは、ブールコンテキストではfalseと解釈され、if0
とtrue ~0
(の補数を意味します。これは、符号付き2の補数整数として解釈された場合0
に値を表します)。-1
その他の値の解釈は、実装に依存していました。
まだ型のない後継者Bの後、Cは型システムを再導入しましたが、それでも前任者の型のない性質に大きく影響されました。
整数と互換性のない別の「ブール」型を追加すると、目的に整数を使用するよりもコンパイラが複雑になります。整数と互換性のある別のブール型を使用すると、0または1以外の値をブールオブジェクトに格納したり、「 0または「1」。与えられた:
someBool = intFunction();
someInt = someBool;
intFunctionがゼロ以外の値を返す場合、someIntが値1を受け取る必要があることを要求すると、通常、上記はより高価になります。
someChar = intFunction();
someInt = someChar;
前者のセマンティクスが必要な場合は、ブール型を使用せずに、次の方法で実現できます。
someChar = !!intFunction();
someInt = someChar;
ブール型を使用して実行できることはすべてブール型なしでも実行でき、多くの場合、文字型を使用するコードはブール型よりも効率的である可能性があるため、実際には存在しなかった(そしてまだ存在しない)ことをお勧めします。それらの必要性。
彼らはそれを入れなかったので。それがスニッピーに聞こえるなら申し訳ありませんが、基本的にそれはそのように定義されていませんでした。
ほとんどの人が#defineTRUEとFALSEを覚えておいてください。
boolは標準であると言うかもしれませんが、10年前に作成されたC99以前は明らかに標準ではありませんでした;)不足しているアイテムが明らかになったときに、彼らはそれを追加しました。
プログラミング言語で欠落しているデータ型を含むすべてを予測できる人はいないからです。