作为头文件的constexpr常量
1. include会复制多份
2. ODR使用
之前有个疑惑
We can include
constants.h
into as many code files as we want, but these variables will only be instantiated once and shared across all code files.来自learncpp 7.9 — Sharing global constants across multiple files (using inline variables) – Learn C++
这个应该是与not inline constexpr 对比,相同的是他们在每个.o文件都会有constexpr,不同的是not inline在exe里面还会有多份constexpr虽然带有作用域标识,inline constexpr会通过linker删除identical只保留一份所以称作instantiated once。
然而,这种方法存在一些不足之处。首先,这些常量现在仅在它们实际被定义的文件(constants.cpp)内被视为编译时常量。在其他文件中,编译器只会看到前向声明,而这并不定义一个常量值(必须由链接器解析)。这意味着在其他文件中,这些常量被视为运行时常量值,而不是编译时常量。因此,在constants.cpp之外的地方,这些变量不能在需要编译时常量的任何地方使用。其次,由于编译时常量通常可以比运行时常量更好地进行优化,编译器可能无法对这些常量进行同样程度的优化。
如果都复制,文件变得大,但可以开优化,编译慢
如果不复制,都以前置声明来处理,连接器去找翻译单元,编译器无法做优化
由于编译器单独编译每个源文件,它只能看到出现在正在编译的源文件中的变量定义(包括任何包含的头文件)。例如,在编译main.cpp时,constants.cpp中的变量定义是不可见的。因此,constexpr变量不能分离到头文件和源文件中,它们必须在头文件中定义。
constexpr 放在头文件才能在include的时候直接复制过去开优化,所以开优化是在编译过程中,链接过程没有优化是吧,如果constexpr在cpp文件,就只能在cpp文件中定义,那么编译过程不可见。
constexpr 出现 那么 static 就可以不出现了,按我目前学到的
头文件header only
链接器会删除副本,对抗单一定义原则,
编译器,需要看到完整的定义,当然也得是单一定义原则,也就是可以先声明,编译器在本翻译单元找定义
pi.h:
#ifndef PI_H
#define PI_H
inline double pi() { return 3.14159; }
#endif
定义写到头文件,能确保副本都一样,header-only library只需要include,不需要链接源文件