File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -51,10 +51,10 @@ extern int a{42}; // 定义(含义同上)
5151
52521. 一个翻译单元中,允许出现一个东西 <sup>※</sup> 的多次声明,但最多只允许出现一次定义;
5353<small>※ 指变量、函数、类型和模板</small>
54- 2. 一个翻译单元中 ,如果 *ODR-使用*了一个符号,那么它最少要出现一次定义。
54+ 2. 整个程序中 ,如果 *ODR-使用*了一个符号,那么它最少要出现一次定义。
55553. 整个程序中,非*内联*的符号最多只允许出现一次定义;
5656
57- 前两条规则规定了 **一个翻译单元中**的定义出现次数。第一条规则说,声明可以多次出现 ,但定义最多只能有一次:
57+ 第一条规则规定了 **一个翻译单元中**的定义出现次数,也即声明可以多次出现 ,但定义最多只能有一次:
5858```cpp
5959 // 多次声明...
6060 void f();
@@ -69,7 +69,7 @@ extern int a{42}; // 定义(含义同上)
6969// int a; // 取消此行注释报错
7070```
7171
72- 第二条规则说的是在什么时候必须要给出一个定义。 在大多数情形下,如果不“使用”这个东西,那么就不需要它的定义。而为了界定“使用”的含义,这里引入了一个术语叫做 ODR-使用(ODR-use)。ODR-使用的正式含义非常复杂,我简单概括为“需要取其地址的行为”。这里还隐含了(变量)读取、写入、(函数)调用以及绑定引用这些情形。
72+ 后两条规则描述了 ** 多个翻译单元在链接成一个程序 ** 时,每个符号允许的定义数量。第二条规则描述定义数量的最小值: 在大多数情形下,如果不“使用”这个东西,那么就不需要它的定义。而为了界定“使用”的含义,这里引入了一个术语叫做 ODR-使用(ODR-use)。ODR-使用的正式含义非常复杂,我简单概括为“需要取其地址的行为”。这里还隐含了(变量)读取、写入、(函数)调用以及绑定引用这些情形。
7373``` cpp
7474// 考察 a 和 c 的使用是否是 ODR-使用
7575int a;
@@ -94,7 +94,7 @@ ld: ...crt0_c.o:crt0_c.c:(.text.startup+0x2e): undefined reference to `main'
9494
9595> 当然,单一定义原则里也规定了什么时候需要类定义而不是前置声明:我[ 之前] ( /ch07/object_relationships ) 已经提到过这条规则,所以这里不再赘述。
9696
97- 最后一条规则不是针对单个翻译单元的,而是描述了 ** 多个翻译单元在链接时 ** 每个符号允许的定义数量 。它说:在大部分情形下最多允许一个符号定义一次,唯有* 内联* 符号是例外。暂时不管“内联”的情形,先来看看一般的例子:
97+ 最后一条规则则则是描述定义数量的最大值 。它说:在大部分情形下最多允许一个符号定义一次,唯有* 内联* 符号是例外。暂时不管“内联”的情形,先来看看一般的例子:
9898``` cpp
9999// a.cpp 里面有一个定义
100100void f () { }
You can’t perform that action at this time.
0 commit comments