重新认识声明与定义(未完工)
我们要牢记白指导说的道理
mq 白在川上曰:
非定义声明,因为 Game 在此处为不完整类型
我能明白其意思,定义一定是声明,声明却不一定是定义。所以用了:“非定义声明”这个词语,很专业的措辞。
不过我觉得大多数普通开发者并不够清楚这一点,看到这段注释同样会感到疑惑。
在他们眼里声明和定义是两种东西,此处如果直接用声明它们可能就不会有理解问题了。例如:“只是声明,不是定义”之类的措辞。
或许我们应该考虑在保证专业以及严谨的情况下,稍微补充解释一下“非定义声明”这个用词。
多文件编译的必要性
翻译单元 (TU)
符号的链接类型 (linkage)
函数和变量,在对外的可见性这方面,有以下几种类型:
- 外部链接 (ODR external linkage):对其他翻译单元可见
- 共享链接 (non-ODR external linkage)
- 内部链接 (internal linkage)
- 无链接 (no linkage)
函数和变量的可见性这一属性,被 C++ 官方称为链接(linkage),是因为符号的可见性处理通常是链接器(ld)负责的,不同类型链接(linkage)的效果,在链接(link)的时候才会生效。
定义在全局(名字空间)中的情况:
int i; // 变量声明并定义为“外部链接”
int f(int x); // 函数声明为“外部链接”
int f(int x) {} // 函数声明并定义为“外部链接”
extern int i; // 变量声明为“外部链接”
extern int f(int x); // 函数声明为“外部链接”
extern int f(int x) {} // 函数声明并定义为“外部链接”
inline int i; // 变量声明并定义为“共享链接”
inline int f(int x); // 函数声明为“共享链接”
inline int f(int x) {} // 函数声明并定义为“共享链接”
static int i; // 变量声明并定义为“内部链接”
static int f(int x); // 函数声明为“内部链接”
static int f(int x) {} // 函数声明并定义为“内部链接”
定义在类(class)中的情况:
struct Class {
int i; // 变量声明并定义为“无链接”
int f(int x); // 函数声明为“外部链接”
int f(int x) {} // 函数声明并定义为“共享链接”
inline static int i; // 变量声明并定义为“共享链接”
inline static int f(int x); // 函数声明为“共享链接”
inline static int f(int x) {} // 函数声明并定义为“共享链接”
static int i; // 变量声明并定义为“外部链接”
static int f(int x); // 函数声明为“外部链接”
static int f(int x) {} // 函数声明并定义为“外部链接”
};