编辑:我已经恢复了原始标题,但实际上我应该问的是:'C++链接器如何处理已在多个目标文件中定义的类方法'
假设我在这些行的标题中定义了一个C++类:
class Klass
{
int Obnoxiously_Large_Method()
{
//many thousands of lines of code here
}
}
Run Code Online (Sandbox Code Playgroud)
如果我编译一些在几个位置使用'Obnoxiously_Large_Method'的C++代码,生成的目标文件是否总是内联'Obnoxiously_Large_Method'的代码,或者它是否会针对大小进行优化(例如,当使用g ++ -Os时)并创建单个实例'Obnoxiously_Large_Method'并像普通函数一样使用它?如果是这样,链接器如何解决已实例化相同函数的其他目标文件之间的冲突?是否存在一些神秘的C++命名空间Juju,它使方法的单独对象实例不会相互冲突?
Mic*_*urr 11
7.1.2函数说明符
带有内联说明符的函数声明(8.3.5,9.3,11.4)声明了一个内联函数.内联说明符向实现指示在调用点处函数体的内联替换优先于通常的函数调用机制.在呼叫点执行此内联替换不需要实现; 但是,即使省略了这种内联替换,仍应遵守7.1.2定义的内联函数的其他规则.
因此,编译器不需要实际"内联"任何函数.
但是,标准也说,
具有外部链接的内联函数在所有翻译单元中应具有相同的地址.
成员函数通常具有外部链接(一个例外是当成员函数属于'local'类时),因此对于获取函数地址的情况,内联函数必须具有唯一的地址.在这种情况下,编译器将安排链接器丢弃除函数的非内联副本的所有实例,并将该函数的所有地址引用修复为保留的那个.
C++98 标准的 [9.3] 节“成员函数”指出:
成员函数可以在其类定义中定义(8.4),在这种情况下它是内联成员函数(7.1.2)。
因此,通常情况下,显式标记类定义中定义的成员函数inline
是不必要的。
在inline
函数说明符上,标准规定:
带有说明符的函数声明(8.3.5、9.3、11.4)
inline
声明内联函数。内联说明符向 [C++ 编译器] 指示,在调用时函数体的内联替换优先于通常的函数调用机制。[但是,C++ 编译器] 不需要在调用时执行此内联替换;
因此,编译器是否会实际内联函数的定义而不是通过通常的函数调用机制来调用它取决于编译器。