ISO/IEC 9899:2011 条款6.9.2——外部对象定义
6.9.2 外部对象定义
语义
1、如果对一个对象的标识符的声明具有文件作用域以及一个初始化器,那么该声明是对该标识符的一个外部定义。
2、对于具有文件作用域且没有一个初始化器、没有一个存储类说明符,或者具有存储类说明符static的对象的标识符的一个声明,构成了一个试验性的定义。如果一个翻译单元对于一个标识符包含了一个或多个试验性的定义,并且该翻译单元不包含对此标识符的外部定义,那么该行为就完全好比该翻译单元包含了对此标识符的一个文件作用域的声明,具有到此翻译单元末尾的复合类型,并且具有一个等于0的初始化器。
3、如果对一个对象的一个标识符的声明是一个试验性的定义,并且具有内部连接,那么所声明的类型不应该是一个不完整类型。
4、例1
int i1 = 1; // 定义,外部连接 static int i2 = 2; // 定义,内部连接 extern int i3 = 3; // 定义,外部连接 int i4; // 试验性定义,外部连接 static int i5; // 试验性定义,内部连接 int i1; // 有效的试验性定义,引用之前的i1 int i2; // 由6.2.2所描述的未定义行为,连接不一致 int i3; // 有效的试验性定义,引用之前的i3 int i4; // 有效的试验性定义,引用之前的i4 int i5; // 由6.2.2所描述的未定义行为,连接不一致 extern int i1; // 引用之前的i1,其连接是外部连接 extern int i2; // 引用之前的i2,其连接是内部连接 extern int i3; // 引用之前的i3,其连接是外部连接 extern int i4; // 引用之前的i4,其连接是外部连接 extern int i5; // 引用之前的i5,其连接是内部连接
5、例2 如果在翻译单元的末尾包含
int i[];
数组i仍然具有不完整类型,那么隐式的初始化器使得它具有一个元素[译者注:相当于定义了int i[1];],它在程序启动时被设置为零。