为什么编译器不会自动内联自由定义的函数?而是导致链接器错误
Why compiler doesn't automatically inline freely defined function ? Instead results in linker error
示例:
// header.h
void foo () // function definition in the file
{
}
// file1.cpp
#include"header.h"
...
// file2.cpp
#include"header.h"
...
以上代码将导致链接器错误。假设编译器自动生成inline foo()
,则不会出现任何链接器错误。
我的问题是从语言的角度。为什么编译器不自动将其设为inline
?这会有什么不同吗?
换句话说,问题是:"如果编译器在定义的每个自由函数前面假设inline
,可能会发生什么错误?">
页眉只是作为页眉文本的复制粘贴处理。编译器不知道你的代码在头文件中,而不是在源文件中,所以它必须对两者进行相同的处理,允许出现错误。语言指定了这一点。
答案是,基本上,C++标准要求它以这种方式运行,所以它确实这样做了。这是一个定义规则的一部分。
实际上,编译器必须生成链接器可见函数,以防您在其他地方实际使用它。例如,以下文件3.cpp必须工作:
void foo();
void call_foo() {
foo();
}
并且为了使其工作,为foo()
生成的代码必须可用于链接器。编译器一次只看一个翻译单元(.cpp
文件,加上其中包含的所有内容(,所以它不知道它实际上生成了两次。的确如此。然后链接器捕获它。
这不会导致链接器错误。它可能会导致链接器错误,但不需要编译器来捕获该错误。
跨模块一致性完全是程序员的责任。C++编译器不需要能够看到,例如,您在两个具有不同类定义的不相关文件中使用了相同的类名。不管发生什么都是你的错。
一般来说,C++编译模型的许多明显奇怪的弱点都与这样一个事实有关,即必须可以通过一次只看一个模块(编译单元(来编译C++程序。需要Is来确保编译时间和空间不会因大型项目而激增。
It可以inline
It(但如果不是static
,它仍然必须单独具有该功能(,但您没有抓住要点。
编译器发现您用相同的签名定义了函数两次。它们可能会有所不同。所以在链接阶段,它会生成一个错误,让你知道发生了什么不好的事情
将声明放在头void foo ();
中,并在cpp文件的一个中实现该函数。
根据C的定义,在链接时自动内联的问题是,是否存在两个同名的不同函数。底层的二进制接口没有维护必要的元数据来解决此类冲突。再加上第三个源文件,它使用(但没有定义自己(具有这样一个名称的函数,它将不知道应该使用哪一个。
我怀疑可能有一些实验性的C编译器(或者更可能是类C编译器(可以做到这一点,但它们在某种程度上肯定会破坏兼容性。
- "error: no matching function for call to"构造函数错误
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- 尝试将unique_ptrs推送到向量时使用纯虚拟函数错误
- C++ OpenCV 卡尔曼滤波器构造函数错误
- C++:用户定义的显式类型转换函数错误
- C++ 合并字符串以'system'函数错误
- C++ wmain 函数错误时使用 Unicode
- 结构数组的构造函数错误,错误消息:没有构造函数实例与参数列表匹配
- C++ 中常量属性的初始化构造函数错误
- 线程 std::调用未知类型,无法专门化函数错误
- 表单显示对话框函数错误,并且不执行下面的语句
- 函数错误 C2059:语法错误:'>'不起作用
- STL向量上出现奇怪的复制构造函数错误
- C++ Visual Studio 重载函数错误:没有重载函数的实例与指定的类型匹配
- C++引用已删除函数错误
- 为什么通过带有文字编号的引用调用会出现"无匹配函数"错误?
- C++ 乘法定义的构造函数错误消息似乎错误
- 在 c++ 代码中将数组传递给函数错误
- FFMPEG avcodec_decode_video2函数错误代码
- 为什么我会收到转换函数错误