types - 有类型与无类型语言

标签 types compiler-construction programming-languages declaration

我在学习 C 和汇编语言在一起。我注意到与 相比,汇编是一种无类型语言。 C 这需要在处理数据之前声明数据类型。但我也了解到,即使是在 中编写的代码C 首先编译成用汇编编写的代码,然后再组装成目标代码。所以这意味着我们在 中使用的数据类型声明C 或任何高级语言只是为了方便 C 编译器。它们对目标代码没有任何特殊影响。那是对的吗?

我收集的是类型声明告诉编译器可以对数据进行哪些操作,数据的大小(需要将数据存储在数据段中),可以存储的最大和最小十进制数的大小。我这样说对吗?

类型声明还有其他好处吗?

最佳答案

在 C 中,我们有一个简单的类型系统,但它并不是特别复杂,可以(并且在实践中经常)通过完全未经检查的强制转换等来规避(出于这些原因,C 通常被称为“弱类型”,这是病态的-defined 并且通常用于抨击一种语言,但至少表明类型不是那么重要。)类型的大小、布局和对齐方式不是固定的,尽管它通常与相同的编译器(版本)一致同一个平台。安 int可能是 14 位大,等等,这些东西是不能保证的(除了 C 标准要求基本整数类型之间有一些排序,例如 short 不能大于 int )。

程序员不知道细节,但编译器知道并且实际上需要。例如,为 foo.y 生成的确切代码哪里struct Foo { int x; short y; };struct Foo foo;取决于例如关于 int 的确切尺寸和 short并在 struct Foo 的填充上,因为它编译为“取 foo 的地址,在 y 中添加 struct Foo 的偏移量,然后使用它”。甚至 struct Foo foo;需要 struct Foo 的确切知识(并且,递归地,它由哪些类型组成) - 生成的代码必须知道确切的 sizeof(struct Foo)在堆栈上保留正确的字节数?类似地,需要类型声明以了解用于数学运算的操作码(iaddfadd 或加法?必须扩展操作数之一,以及扩展到什么大小?)、比较、进行指针算术时的步长( p + n 实际上添加了 n * sizeof(*p) ) 等。这也阻止了对不存在的成员的访问(并且,通过扩展,将值传递给然后会遇到此问题的函数 - 即类型不匹配),但这更像是一个方便的副作用- 编译器认为这是一个错误,因为不知道要发出什么代码,而不是因为它认为程序员就像 child 一样,必须被监视并保持有序。

在汇编语言中(通常 - 就在昨天,我读到了微软研究院的一个项目,该项目为操作系统开发了一种类型化、可验证的汇编语言,通过构造可以安全地抵御某些错误),您实际上并没有类型。你有字节。你从某个位置获取 N 个字节,对它们做一些事情,然后将它们存储到某个位置。是的,寄存器固定为某些字大小,有些可能用于特殊类型的值(例如,具有 80 位或更多位的专用浮点寄存器),但基本上,您可以在任何地方存储您喜欢的任何内容。没有人会阻止您在某处存储 8 个字节,稍后仅读取后 4 个字节并将它们与您的循环计数器相加以形成一个地址来存储返回值。

在其他语言中,类型系统要强大得多,同时允许进行大量扩展以允许更高级别的编程,例如抽象出确切的类型(以及它们的布局和类型),并只采用满足特定约定的任何类型.它允许类型签名,例如 [a] -> a ,这是一个函数,它接受一个包含任何类型值的列表(只要它是同质的,例如整数列表、字符串列表、字符列表列表等)并返回其中一个元素,不带 "删除”(例如转换为 void * )类型。 (根据实现,它实际上可能会生成多个实现,每个实现都针对具有已知布局的单个类型,以提高性能 - 但这不会泄漏给程序员。)

关于types - 有类型与无类型语言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6229061/

相关文章:

sql - 动态转换数组元素的类型以匹配 PostgreSQL 查询中的某些表达式类型

python - 检查构造函数参数有效性的 pythonic 方法是什么?

c# - 在 C#.Net 中将小数转换为字符串的问题

c - 在 OSX 上使用 clang 时,什么控制自动添加的命令行选项?

perl - 为什么 Perl 是大多数字符串操作任务的最佳选择?

powershell - 数字在Powershell的内部变量中更改

gcc - -shared 和 -bundle gcc 标志有什么区别

c# - 试图在编译时分配一个大数字

c# - 空字符串的目的是什么?

linux - 哪种语言适合Linux及相关编程?