在C或C++链接器中是否有任何类型检查?

Ric*_*ver 3 c c++ x86-64 clang

我正确地说连接器没有进行功能参数检查.它们不检查函数调用的数量或类型,也不检查全局数据引用的类型.所有连接体都是如此吗?

我在x86-64上使用Clang瞄准Linux.链接器是否检查引用是否在正确的段中?或者就链接器而言,外部引用实际上只是一个void*?

我来自高级语言背景C#和Scala,所以对于那些沉浸在低级别世界中的人来说,这似乎是显而易见的.我在汇编程序中编写了几个函数(系统调用),我注意到汇编程序中没有外部函数的参数原型.

上下文:我实际上是在编写一个编译器.目前我的目标是使用汇编程序函数进行系统调用的预处理C .i文件,但替代方案是C++,汇编程序甚至是机器代码,所以我试图权衡成本和收益,特别是类型检查.汇编器/编译器/ 链接器我可以用来检查我自己的程序及其函数原型生成的正确性.

Jos*_*ley 8

正如@Yakk所解释的那样,函数可以根据它们的参数进行重载,因此编译器会生成包含参数及其类型信息的错位函数名.链接器主要只是检查符号名称和大小,但由于重整确保函数的名称不同,不匹配的参数将不会链接.

函数返回类型不是修改的一部分(因为返回类型上的重载是不合法的),所以如果你int test()在一个翻译单元中声明并float test()在另一个翻译单元中调用,链接器将不会捕获它,并且你将得到不好的结果.

类似地,链接器不会检查全局变量的类型(以及类的静态成员等),因此如果您extern int test;在一个转换单元中声明并float test;在另一个转换单元中定义,则会得到错误的结果.

在某些情况下,链接器可以比较两个不同转换单元中符号的大小,并且可以以这种方式捕获一些问题.

实际上,这在普通的C++开发中很少成为问题,因为只要> 1翻译单元需要一个函数或变量或类,你就会在一个包含在两个翻译单元中的头文件中声明它,并且编译器会捕获它链接器运行之前的任何错误.(可能存在问题的一个实例是,如果您使用外部二进制库,并且您拥有的头文件与库不匹配.)

  • 实际上,当您使用与外部库的内容不匹配的头文件时,这可能会出现问题. (2认同)