7.1.2 类型安全连接
对名字修饰还可以带来一个额外的好处。在C中,如果用户错误地声明了一个函数,或者更糟糕地,一个函数还没声明就调用了,而编译器则按函数被调用的方式去推断函数的声明。这是一个特别严重的问题。有时这种函数声明是正确的,但如果不正确,就会成为一个很难发现的错误。
在C++中,所有的函数在被使用前都必须事先声明,因此出现上述情况的机会大大减少了。编译器不会自动添加函数声明,所以我们应该包含一个合适的头文件。然而,假如由于某种原因还是错误地声明了一个函数,可能是通过自己手工声明,也可能是包含了一个错误的头文件(也许是一个过期的版本),名字修饰会给我们提供一个安全网,这也就是人们常说的类型安全连接(type-safe linkage)。
请看下面的几个例子。在第一个文件中,函数定义是:
在第二个文件中,函数在错误的声明后调用:
即使知道函数实际上应该是f(int),但编译器并不知道,因为它被告知—通过一个明确的声明—这个函数是f(char)。因此编译成功了,在C中,连接也能成功,但在C++中却不行。因为编译器会修饰这些名字,把它变成了诸如f_int之类的名字,而使用的函数则是f_char。当连接器试图找到f_char引用时,它只能找到f_int,所以它就会报告一条出错信息。这就是类型安全连接。虽然这种问题并不经常出现,但一旦出现就很难发现,尤其是在一个大项目中。这是利用C++编译器查找C语言程序中很隐蔽的错误的一个例子。