《Modern C》同一标识符多声明规则与编译报错疑问
问题:为何重复声明局部变量会与《Modern C》中的规则冲突?
首先引用《Modern C》中的相关内容:
截至目前的示例中,我们见过两种不同特性的名称:objectsC(如
i和A),以及functionsC(如main和printf)。与对象或函数的声明(同一标识符可拥有多个声明)不同,对象或函数的定义必须唯一。也就是说,一个可运行的C程序中,所有被使用的对象或函数都必须有且仅有一个定义(否则执行时无法找到对应实体,或出现执行不一致问题)。
我尝试编写如下代码(位于main函数内部):
// Declarations int i; int i;
却得到编译报错:
try.c: In function 'main': try.c:7:9: error: redeclaration of 'i' with no linkage int i; ^ try.c:6:9: note: previous declaration of 'i' was here int i; ^
请问为何会出现该编译报错,是否与书中描述的规则冲突?
解答
这并不冲突,核心是忽略了C语言中标识符的链接属性这一关键前提:
- 你写的
int i;位于函数内部(局部作用域),属于**无链接属性(no linkage)**的声明。C标准明确规定:同一作用域内,无链接的标识符不能重复声明,否则编译器直接报错。 - 《Modern C》中提到的“同一标识符允许多个声明”,针对的是**外部链接(external linkage)或内部链接(internal linkage)**的标识符:
- 外部链接:比如在全局作用域声明的
int i;(这是一种试探性定义,属于声明范畴),可以在多个源文件中重复声明,最终链接阶段只会生成一个唯一的定义。 - 内部链接:比如用
static int i;声明的全局变量,在同一源文件的不同位置可以重复声明,因为它的作用域被限制在当前源文件内。
- 外部链接:比如在全局作用域声明的
简单总结:局部作用域的无链接变量不允许多次声明,而书中的规则针对的是全局作用域下带有链接属性的变量或函数。
内容的提问来源于stack exchange,提问作者Omar
相关产品推荐
相关产品推荐

