2012-04-06 17 views
3

long double x = 8.99999999999999999の場合、 'L'が付加されていないため、値はdoubleとして保存されます。変数xをfloat型のlong doubleと宣言したときに、Cコンパイラが型推論を実行できないのはなぜですか?なぜCコンパイラは型推論を行えないのですか?

+5

標準のC仕様では、型推論を行うべきではないと述べているためです。 * Ocaml *、* Haskell *、さらにはC++ 11 *の言語仕様を見てください。 –

+0

@BasileStarynkevitch:それを答えに入れることができます。 – kay

+0

既に型を宣言したときに推論するものは? – Dikei

答えて

2

Cがで、タイプセーフでないため、Cコンパイラはタイプ推論を行いません。あなたは簡単に物事を無効にキャストすることができます。ルール違反ではありません。これは、少なくともCの型推論は近似的なものに過ぎないことを意味し、コンパイラにあなたの型が間違っていたかどうかの手がかりを与えてくれることを意味します。

なぜCは型推論をしないのですか?C言語の型は、論理的な関係を強制するか、言語内で真理値を符号化するためのではありません。です。いくつかのレベルでは、サウンドタイプのシステム(Has​​kell、OCaml、SML、Coqなど)を持つ言語は、タイプがであることを意味します。あなたには何かがあります:タイプからあなたのプログラムについて書き留めることができます。 (これの興味深い例については、Philip Wadlerの「Theorem's for Free!」作業を参照してください。)

だからなぜ Cを使用しますか?その理由は、コンパイラがあるレベルでは、メモリに格納されたデータをどのように整理するかをコンパイラが知る必要があるということだけです。代わりに、論理的な整合性のため、Cでの種類は、私が構造内にこのint型を置くべき事柄がレイアウトされているどのように伝えるために、肉、など...

ある代わりに、Cはに熟語の数を持ってい以上をエミュレートタイプセーフな言語の標準機能例えば、パラメトリック多形性を表現するために、通常、ボイドポインタが使用されます。 (例えば、任意のデータ型へのポインタを含むリストを持つことができます)実際には、Cでは、異なるデータ型を指すリストをエンコードすることができます。従来の関数型言語では、リストの帰納型にはすべての要素が同じ型である必要がありますが、Cではinerection型と行を簡単にエンコードできます(Cでは、リスト要素に識別子を付けるなど)。

ありタイプとCのメモリ安全な方言は、いくつかの場所では、多型がまだの細かな点のあなたは多く与えながら、ボイドポインタのようなものの出現を置き換えない例としてCycloneを参照していますC言語。

1

long double x = 3.0の場合。値3.0はdoubleとして格納されます。

それはlong doubleとして3.0を格納します。

+0

あなたは正しいです..私は別の値を意味しました..質問を編集しました... – KawaiKx

4

the C standard標準では、これがではなく、であることを明示的に指定しているため、コンパイラは型推論を行いません。浮動小数点定数の

セクション6.4.4.2は言う:

unsuf fiがFL浮動定数は、二重入力したXED。文字fまたはFの後には float型が付きます。文字lまたはLの後に接尾辞が付いている場合は、long double型です。


なぜ標準がそう言うのでしょうか?たぶん、それはコンパイラを簡素化するので、それをする必要はありません(正直言って、わかりません)。

4

C言語が最初に開発された1970年代の初め、コンパイラを実行するコンピュータは、メモリがほとんどなく低速でした。このため、コンパイラが簡単になるように言語を設計する必要があり、コンパイルが高速になる可能性があります。単純なコンパイラでは、コンパイラが推論する必要があるたびにCPUとメモリを使用するため、プログラマにすべてを伝える必要があります。

もう1つ、私は同じように重要な理由は、Cを開発して使用していた人が最初にオペレーティングシステムを作成していて、巧みにしようとしなかった言語を欲しかったということです。オペレーティングシステムの作成は、コンパイラの動作を推測することなく、十分に手間がかかります。何が起こるかを非常に正確に制御する必要がありました。その意味で、オペレーティングシステムライターにはより単純な言語が大きなメリットをもたらす可能性があります。

これらのことから、C言語は、後の数十年に設計された高水準言語が今やアプリケーションプログラミングを目指す多くの機能なしで終わった。オブジェクト指向、型推論、ガベージコレクション、例外なし、スレッド化のサポートはありません。

将来的にC言語が変更される可能性があります(実際には最新のC標準にはネイティブスレッドがありますが、オプションであると思いますが)あなたは別の言語が欲しい。文字通り何千もの興味深い言語があります。

+2

これはすべての推測です。私たちが知っていることは、Dennis RitchieがそのBCPL遺産に基づいてそのように言語を設計したことだけです。もう一つの説明は、リッチーは実際にはじまりのコンパイラライターではなく、その時にどこの角度が踏み出されるのかと心配していました。 – EJP

1

他の人は標準状態that unless suffixed, a floating point constant is a doubleと述べています。さて、計算の複雑さからその背後にある論理的根拠を見てみましょう。標準はまた、long double>=doubleを指摘しました。sizeof(double)=8sizeof(long double)=16のシステムを考えてみましょう。さて、あなたの特定の例では、接尾辞がありません。コンパイラは64-bitの精度の浮動小数点数を計算し、残りの8バイトをゼロにします。しかし、あなたが示唆しているように型推論を行う場合は、今度は浮動小数点数128-bitを得るために計算を行わなければなりません。

そしてconverting a floating point number into binaryの表現は簡単な作業ではないので、コンパイラは可能な限り辛抱強くしようとします。特にこの例では、8.99999999999999999long doubleにアップグレードする必要はありません。これは、妥当な精度でdoubleに絞ることができるためです。

+0

イタリック体のステートメントについて:そうではありません。 #1)私はこれについて標準で何も表示されません。 #2)私のGCCのコピーでは、 'double'変数に収まらない巨大な浮動小数点定数を割り当てると 'inf'として出力されます。標準によれば、定数に 'L'をつけると変数に正しく格納されます。 – ArjunShankar

+0

@ArjunShankarあなたのシステムでダブルとロングダブルのサイズが同じであるかどうかチェックしましたか?私はdouble doubleがdoubleよりも大きいシステムを参照していますか? –

+0

はい私はチェックしました。そして、彼らは同じではありません。 – ArjunShankar

関連する問題