为什么C编译器可以';你不做类型推断吗?

为什么C编译器可以';你不做类型推断吗?,c,types,inference,C,Types,Inference,如果long double x=8.9999999999999999,则该值存储为double,因为没有附加“L”。既然我已经将变量x声明为long doublefloat类型,为什么C编译器不能进行类型推断 如果是长双x=3.0。值3.0存储为双精度 不是真的!将3.0存储为长双精度编译器不执行类型推断,因为标准明确规定不应执行此操作 关于浮动常数的第6.4.4.2节规定: 非固定流动常数具有双重类型。如果以字母f或f作为后缀,则具有 输入float。如果后缀为字母l或l,则其类型为long

如果
long double x=8.9999999999999999
,则该值存储为
double
,因为没有附加“L”。既然我已经将变量
x
声明为
long double
float类型,为什么C编译器不能进行类型推断

如果是长双x=3.0。值3.0存储为双精度


不是真的!将3.0存储为
长双精度

编译器不执行类型推断,因为标准明确规定不应执行此操作

关于浮动常数的第6.4.4.2节规定:

非固定流动常数具有双重类型。如果以字母f或f作为后缀,则具有 输入float。如果后缀为字母l或l,则其类型为long double



标准为什么这么说?可能是因为它简化了编译器,而不必这样做(老实说,我不确定)。

在20世纪70年代早期,当C语言首次开发时,运行编译器的计算机速度很慢,内存很少。因此,有必要设计语言,使编译器变得简单,从而使编译速度更快。一个简单的编译器需要程序员告诉它一切,因为每次编译器需要推理时,它都使用CPU和内存

另一个,我认为同样重要的原因是,开发和使用C语言的人最初是用它编写操作系统的,他们想要一种不想变得聪明的语言。编写操作系统非常复杂,不必猜测编译器可能做什么或不做什么:它们需要非常精确地控制所发生的事情,从这个意义上讲,一种更简单的语言对操作系统编写者来说是一大好处

由于这些原因,C最终没有了许多高级语言在以后几十年中设计并用于应用程序编程的功能。它没有面向对象,没有类型推断,没有垃圾收集,没有异常,也不支持线程


在未来,C可能会被更改为有这样的东西(事实上,最新的C标准现在有本机线程,但我相信它们是可选的),但总的来说,如果你想要这些东西,你需要一种不同的语言。有成千上万种有趣的语言可供选择。

正如其他人所说的标准状态
,除非有后缀,否则浮点常量是双精度的。现在,让我们从计算复杂性的角度来了解它背后的基本原理。标准还注意到:<代码> long double >=double < /代码>,现在考虑一个系统:<代码> siZeof(double)=8 < /COD>和<代码> siZeof(long double)=16 < /Cord>。现在,在没有后缀的特定示例中,编译器只需计算一个
64位
精度浮点数,并将剩余的8个字节归零。但是,如果它按照您的建议进行类型推断,那么它现在必须进行计算,以生成一个
128位的
浮点数


而且表示并不是一件容易的事情,所以编译器尽量小气。特别是在本例中,不需要将
8.999999999999999
升级为
long double
,因为它可以以合理的精度压缩为
double

C编译器不进行类型推断,因为C不是类型安全的。您可以轻松地将东西威利·尼利(willie nilly)抛向虚空、虚空指针,然后再抛回。这并不违反规则。这意味着,至少,任何类型的C类型推断都是近似的,而且最好让编译器为您提供有关类型错误的线索

至于为什么C不进行类型推断:C中的类型不是为了强制逻辑关系,也不是为了在语言中编码真理。在某种程度上,具有声音类型系统的语言(Haskell、OCaml、SML、Coq等)希望这些类型告诉您一些事情:您可以从这些类型中写出一个定理。(参见菲利普·瓦德勒的“免费定理!”,这是一个有趣的例子!)

那么为什么C使用类型呢?原因纯粹是编译器需要知道——在某种程度上——如何组织存储在内存中的数据。C中的类型不是逻辑上的一致性,而是告诉你事情是如何安排的,我应该把这个int放在结构中的什么地方,等等

相反,C有许多习惯用法来模拟类型安全语言中的更多标准特性。例如,空指针通常用于表示参数多态性。(例如,您可以有一个列表,其中可以包含指向任何数据类型的指针。)事实上,它做的更多,在C中,您可以对指向不同数据类型的列表进行编码。在传统的函数式语言中,列表的归纳类型要求所有元素都是相同的类型,而在C语言中,您可以轻松地对类型和行进行编码(例如,在C语言中,可以通过使用标识符标记列表元素来实现这一点)


C语言有一些类型和内存安全的方言,例如,在某些地方,多态性确实取代了诸如空指针之类的出现,同时还提供了C语言的许多细节。

因为标准C规范规定它不应该进行类型推断。查看Ocaml、Haskell甚至C++11语言规范,了解具有某种类型推断的语言。@BasileStarynkevitch:你可以把它作为一个答案。当你已经声明了类型时,要推断什么?这里的限制因素是什么?这是一件非常复杂的事情吗?如果普通双精度和长双精度有不同的表示,它应该能够直接使用长双精度表示,因为常量值是已知的。你确定这与你的实际问题相符吗?这都是猜测。我们只知道丹尼斯·里奇