【发布时间】:2011-07-17 06:43:15
【问题描述】:
为什么这段代码在 C 中有效,而在 C++ 中无效?
int i = 5;
int i; // but if I write int i = 5; again I get error in C also
int main(){
// using i
}
【问题讨论】:
标签: c++ c declaration
为什么这段代码在 C 中有效,而在 C++ 中无效?
int i = 5;
int i; // but if I write int i = 5; again I get error in C also
int main(){
// using i
}
【问题讨论】:
标签: c++ c declaration
Tentative definition is allowed in C but not in C++.
暂定定义是没有存储类说明符和初始化器的任何外部数据声明。
C99 6.9.2/2
为具有文件范围没有初始化程序的对象声明标识符,以及 没有存储类说明符或带有存储类说明符静态,构成一个 暂定定义。如果一个翻译单元包含一个或多个暂定定义 标识符,并且翻译单元不包含该标识符的外部定义,则 该行为就像翻译单元包含该文件的文件范围声明一样 标识符,具有作为翻译单元末尾的复合类型,具有初始值设定项 等于 0。
所以int i 是一个暂定定义。 C 编译器会将所有暂定定义组合成一个 i 定义。
在 C++ 中,由于One Definition Rule(第 3.2/1 节 ISO C++),您的代码格式错误
任何翻译单元不得包含多个变量的定义、函数、类类型、枚举类型或模板。
// 但是如果我再次写
int i = 5;我也会在 C 中得到错误
因为在这种情况下,由于初始化程序 (5),它不再是一个暂定定义。
仅供参考
J.5.11 多个外部定义
一个对象的标识符可能有多个外部定义,无论是否显式使用关键字 extern;如果定义不一致,或者不止一个被初始化,则行为未定义 (6.9.2)。
【讨论】:
要更好地理解暂定定义,请转至this
【讨论】:
这被称为暂定定义。仅在 C 中允许。
暂定定义是任何外部的 没有存储的数据声明 类说明符,没有初始化器。 A 暂定定义变为完整 定义如果结束 已到达翻译单元,但没有 定义出现了 标识符的初始化程序。在 这种情况,编译器保留 对象的未初始化空间 已定义。
以下陈述显示正常定义和暂定定义。
int i1 = 10; /* definition, external linkage */
static int i2 = 20; /* definition, internal linkage */
extern int i3 = 30; /* definition, external linkage */
int i4; /* tentative definition, external linkage */
static int i5; /* tentative definition, internal linkage */
int i1; /* valid tentative definition */
int i2; /* not legal, linkage disagreement with previous */
int i3; /* valid tentative definition */
int i4; /* valid tentative definition */
int i5; /* not legal, linkage disagreement with previous */
C++ 不支持暂定定义的概念:没有存储类说明符的外部数据声明始终是一个定义。
【讨论】: