long double x = 8.99999999999999999
の場合、 'L'が付加されていないため、値はdouble
として保存されます。変数x
をfloat型のlong double
と宣言したときに、Cコンパイラが型推論を実行できないのはなぜですか?なぜCコンパイラは型推論を行えないのですか?
答えて
Cがで、タイプセーフでないため、Cコンパイラはタイプ推論を行いません。あなたは簡単に物事を無効にキャストすることができます。ルール違反ではありません。これは、少なくともCの型推論は近似的なものに過ぎないことを意味し、コンパイラにあなたの型が間違っていたかどうかの手がかりを与えてくれることを意味します。
なぜCは型推論をしないのですか?C言語の型は、論理的な関係を強制するか、言語内で真理値を符号化するためのではありません。です。いくつかのレベルでは、サウンドタイプのシステム(Haskell、OCaml、SML、Coqなど)を持つ言語は、タイプがであることを意味します。あなたには何かがあります:タイプからあなたのプログラムについて書き留めることができます。 (これの興味深い例については、Philip Wadlerの「Theorem's for Free!」作業を参照してください。)
だからなぜは Cを使用しますか?その理由は、コンパイラがあるレベルでは、メモリに格納されたデータをどのように整理するかをコンパイラが知る必要があるということだけです。代わりに、論理的な整合性のため、Cでの種類は、私が構造内にこのint型を置くべき事柄がレイアウトされているどのように伝えるために、肉、など...
ある代わりに、Cはに熟語の数を持ってい以上をエミュレートタイプセーフな言語の標準機能例えば、パラメトリック多形性を表現するために、通常、ボイドポインタが使用されます。 (例えば、任意のデータ型へのポインタを含むリストを持つことができます)実際には、Cでは、異なるデータ型を指すリストをエンコードすることができます。従来の関数型言語では、リストの帰納型にはすべての要素が同じ型である必要がありますが、Cではinerection型と行を簡単にエンコードできます(Cでは、リスト要素に識別子を付けるなど)。
ありタイプとCのメモリ安全な方言は、いくつかの場所では、多型はがまだの細かな点のあなたは多く与えながら、ボイドポインタのようなものの出現を置き換えない例としてCycloneを参照していますC言語。
long double x = 3.0の場合。値3.0はdoubleとして格納されます。
それはlong double
として3.0を格納します。
あなたは正しいです..私は別の値を意味しました..質問を編集しました... – KawaiKx
the C standard標準では、これがではなく、であることを明示的に指定しているため、コンパイラは型推論を行いません。浮動小数点定数の
セクション6.4.4.2は言う:
unsuf fiがFL浮動定数は、二重入力したXED。文字fまたはFの後には float型が付きます。文字lまたはLの後に接尾辞が付いている場合は、long double型です。
なぜ標準がそう言うのでしょうか?たぶん、それはコンパイラを簡素化するので、それをする必要はありません(正直言って、わかりません)。
C言語が最初に開発された1970年代の初め、コンパイラを実行するコンピュータは、メモリがほとんどなく低速でした。このため、コンパイラが簡単になるように言語を設計する必要があり、コンパイルが高速になる可能性があります。単純なコンパイラでは、コンパイラが推論する必要があるたびにCPUとメモリを使用するため、プログラマにすべてを伝える必要があります。
もう1つ、私は同じように重要な理由は、Cを開発して使用していた人が最初にオペレーティングシステムを作成していて、巧みにしようとしなかった言語を欲しかったということです。オペレーティングシステムの作成は、コンパイラの動作を推測することなく、十分に手間がかかります。何が起こるかを非常に正確に制御する必要がありました。その意味で、オペレーティングシステムライターにはより単純な言語が大きなメリットをもたらす可能性があります。
これらのことから、C言語は、後の数十年に設計された高水準言語が今やアプリケーションプログラミングを目指す多くの機能なしで終わった。オブジェクト指向、型推論、ガベージコレクション、例外なし、スレッド化のサポートはありません。
将来的にC言語が変更される可能性があります(実際には最新のC標準にはネイティブスレッドがありますが、オプションであると思いますが)あなたは別の言語が欲しい。文字通り何千もの興味深い言語があります。
これはすべての推測です。私たちが知っていることは、Dennis RitchieがそのBCPL遺産に基づいてそのように言語を設計したことだけです。もう一つの説明は、リッチーは実際にはじまりのコンパイラライターではなく、その時にどこの角度が踏み出されるのかと心配していました。 – EJP
他の人は標準状態that unless suffixed, a floating point constant is a double
と述べています。さて、計算の複雑さからその背後にある論理的根拠を見てみましょう。標準はまた、long double>=double
を指摘しました。sizeof(double)=8
とsizeof(long double)=16
のシステムを考えてみましょう。さて、あなたの特定の例では、接尾辞がありません。コンパイラは64-bit
の精度の浮動小数点数を計算し、残りの8バイトをゼロにします。しかし、あなたが示唆しているように型推論を行う場合は、今度は浮動小数点数128-bit
を得るために計算を行わなければなりません。
そしてconverting a floating point number into binaryの表現は簡単な作業ではないので、コンパイラは可能な限り辛抱強くしようとします。特にこの例では、8.99999999999999999
をlong double
にアップグレードする必要はありません。これは、妥当な精度でdouble
に絞ることができるためです。
イタリック体のステートメントについて:そうではありません。 #1)私はこれについて標準で何も表示されません。 #2)私のGCCのコピーでは、 'double'変数に収まらない巨大な浮動小数点定数を割り当てると 'inf'として出力されます。標準によれば、定数に 'L'をつけると変数に正しく格納されます。 – ArjunShankar
@ArjunShankarあなたのシステムでダブルとロングダブルのサイズが同じであるかどうかチェックしましたか?私はdouble doubleがdoubleよりも大きいシステムを参照していますか? –
はい私はチェックしました。そして、彼らは同じではありません。 – ArjunShankar
- 1. F#型推論(コンパイラ出力)
- 2. コンパイラがこの選択呼び出しの型を推論できないのはなぜですか?
- 3. Scalaが_の型を推論できないのはなぜですか?
- 4. C#コンパイラが汎用シグネチャの代理人を推論できないのはなぜですか?
- 5. なぜ型推論がここで機能しないのですか?
- 6. F#がこの型を推論するのはなぜですか?
- 7. ジェネリック型を推論するためにC#コンパイラを取得するには?
- 8. C++テンプレート非型パラメータの型推論
- 9. この例ではスカラが型パラメータを推論できないのはなぜですか?
- 10. コンパイラが型変換を実行しないのはなぜですか?
- 11. Kotlin:単項プラス/マイナスが代入からジェネリック型を推論できないのはなぜですか?
- 12. これらの型引数を推論できないのはなぜですか?
- 13. C++の "型減算"とHaskellの "型推論"の違いは何ですか?
- 14. F#型推論
- 15. 型コンストラクタの型推論
- 16. なぜF#の型推論でこれを処理できないのですか?
- 17. GHCの型推論は
- 18. 値の型推論は
- 19. 推論の型が制約から型を決定できない理由
- 20. 自動型推論
- 21. スカラパターンマッチングと型推論
- 22. ハスケル推論型エラー
- 23. この場合、1引数のインスタンスメソッドのBiConsumerに対する型推論はなぜ異なるのですか?
- 24. なぜ3とx(3に割り当てられた)はHaskellで推論型が異なるのですか?
- 25. Java Generics Silly Thing(なぜ私は型を推測できないのですか?)
- 26. スウィフトObjectMapperの型推論
- 27. ジェネリックメソッドの型引数の型推論
- 28. 一般的な引数型(Delphi)に基づく型推論
- 29. 型推論入力paramenters
- 30. オプションのパラメータを持つジェネリック型を推論することができない
標準のC仕様では、型推論を行うべきではないと述べているためです。 * Ocaml *、* Haskell *、さらにはC++ 11 *の言語仕様を見てください。 –
@BasileStarynkevitch:それを答えに入れることができます。 – kay
既に型を宣言したときに推論するものは? – Dikei