【发布时间】:2015-03-21 08:49:23
【问题描述】:
我是否正确地说链接器不进行函数参数检查。他们不检查函数调用的数量或类型,也不检查全局数据引用的类型。所有链接器都这样吗?
我在 x86-64 上使用面向 Linux 的 Clang。链接器是否检查引用是否在正确的段中?或者就链接器而言,外部引用实际上只是一个 void *?
我来自高级语言背景 C# 和 Scala,因此对于那些沉浸在低级世界中的人来说,这似乎很明显。我在汇编器中编写了几个函数(系统调用),我注意到汇编器中没有外部函数的参数原型。
上下文:我实际上正在编写一个编译器。目前,我的目标是预处理 C .i 文件,其中包含用于系统调用的汇编程序函数,但替代方案是 C++、汇编程序甚至机器代码,因此我试图权衡成本和收益,尤其是类型检查的成本和收益。汇编器/编译器/链接器我可以用来检查我自己的程序的正确性及其函数原型的生成。
【问题讨论】:
-
可能你永远不会遇到这些类型的错误,编译器会在链接开始之前抛出错误。
-
Cyber 是正确的 - 原则上,链接器只处理地址(当然还有符号名称)。
-
在 C++ 中,名称(通常?)与类型混淆,因此类型不匹配将导致无法找到符号:这主要是因为重载函数的能力。我不知道非函数变量,我从来没有遇到过问题。 C++ 的链接阶段未指定,并且修饰不一致(在实际实践中!不同的编译器以不同的方式修饰符号),所以我不能说比通常更多。在 C 中,它们(通常?)不使用类型进行管理,因为不可能重载。 C的link-stage规范我不是很了解,但是比较一致。
-
通常链接器所做的唯一检查是检查指针类型是否相同大小(例如,您不会将 32 位模块链接到 64 位程序,反之亦然)指出,原型修改是为了允许在 C++ 中重载,因此名称不会出现,因为它们是用源代码编写的。