是在编译到静态库的头文件中定义的函数实现

Are function implementations defined inside header file compiled into static library?

本文关键字:文件 定义 函数 实现 编译 静态      更新时间:2023-10-16

假设我们有很多治疗师,他们的课程和阻抗是这样的:

// header.h
#ifndef MYHEADER
#define MYHEADER
class myClass {
public:
    int one()
    {
        return 1;
    }
    int two();
};
#endif // MYHEADER

以及一些带有一些功能实现的cpp文件:

// header_impl.cpp
#include "header.h"
int myClass::two()
{
    return 2;
}

将其编译到.lib(.a)库捆绑包中以获得int one()的实现,或者它将保留在头中并仅在使用lib的人倾向于在那里的代码中使用它的情况下进行编译(并且将被编译到他的代码中,但更新的会出现在.lib(-a)文件中吗)?

那么,在头文件中定义的函数实现是否被编译到静态库中?

假设函数本身没有被任何库函数使用,并且没有库函数取其地址[生成函数指针],那么编译器就没有理由对其生成"真正的函数"。当然,由于内联实际上是一个"编译器决定"的问题,编译器完全有可能决定不内联使用函数,事实上,在编译它的对象文件中创建一个。

但一般来说,对于小函数,不,它只作为源代码存在于头中,然后在任何调用它的地方内联。

也许,因为cpp几乎肯定会在静态库中包含该标头。通常,仅仅因为它是在类中定义的,并不会强制它是内联的,但它确实指定了函数有一个ODR异常(我想我称之为内联链接;稍后会详细介绍)。因此,根据函数及其在静态库中的使用情况,它可能有实际定义,也可能没有实际定义,这取决于编译器是否将其内联以及是否正在使用它。

如果编译器决定不内联您的函数,那么当您从与静态库链接的exe#include该标头时,您可能认为应该重新定义它,并打破一个定义规则。但是,你错了。因为方法是在类主体中定义的,这一事实将函数标记为具有ODR预期。最终取决于编译器将选择哪个定义(静态库中的定义或exe/whatever中的定义)。它很可能会选择它看到的第一个。

注意:您可以通过在类主体之外定义函数并使用inline关键字来实现ODR异常。