每次谷歌搜索都会将其解释为";变量的名称";,但我有一种感觉,标识符和标识符的名称之间有区别。标识符是否更像一个具有名称、范围、链接和底层对象等属性的对象?我问这个问题是因为我在阅读C标准时遇到了一些麻烦。例如,摘录
int main(){
int x;
extern int x;
}
未能编译,而
int main(){
int x;
if(1){extern int x;}
}
编译成功。在这个问题中,第一个片段的失败是从C标准的6.2.2.6中解释的,该标准规定局部变量没有联系。然而,在第二个片段中,局部变量仍然没有链接,也没有冲突。现在,6.2.2.4规定
对于在该标识符的先前声明可见的作用域中使用存储类说明符extern声明的标识符,如果先前声明指定内部或外部链接,后面声明中标识符的链接与前面声明中指定的链接相同公告如果没有可见的先前声明,或者先前声明未指定链接,则标识符具有外部链接。
我的解释是,这条规则在两个片段中都有效,但在第一个片段中,x
的底层对象的唯一性通过6.2.1.2触发了约束冲突,因为相同的标识符名称用于具有相同作用域和名称空间的两个不同对象。不过,这并不是我刚才所提出的问题的答案所作出的解释。在第二个片段中,链接类型仍然存在冲突,那么更改extern
声明的范围是否会更改本地声明的可见性?从C标准的抽象角度思考链接的最佳方式是什么(不使用像gcc或clang这样的实际实现作为示例(?
"标识符";是语言语法的一个元素。预处理后,所有令牌都是以下之一:关键字、标识符,常量和字符串文字或标点符号。
如果令牌以字母(或下划线(开头,则它只能是关键字或标识符。如果它不在关键字表中,那么它就是一个标识符。有关此方面的更多技术细节,请参见C标准的附录A。
在您的程序中,x
和main
是标识符,int
、if
和extern
是关键字,1
是常量,其他一切都是标点符号。
标识符用作实体的名称。相同的标识符可以在不同的作用域中用于指定不同的实体(或相同的实体(Linkage是标识符与实体关联的过程的名称。
有时标准使用";标识符";指由标识符识别的实体,这在6.2.1/5:中有介绍
除非另有明确说明,否则本国际标准使用术语"标识符"来指代某个实体(与句法结构相反(时,它指的是相关名称空间中的实体,其声明在标识符出现时可见。
第一个代码是错误的,因为6.7/3:
如果一个标识符没有链接,则在相同的作用域和名称空间中,标识符(在声明符或类型说明符中(的声明不应超过一个,除非:[…]
int x;
没有链接,因此在同一范围内不应存在x
的另一个定义。(例外情况清单与本案无关(。
在第二个代码中,没有违反6.7/3,因为第二个声明与第一个声明不在同一范围内。您引用的文本解释了extern int x;
命名的实体与int x;
命名的实体不同,这很好。
第二个程序具有未定义的行为(无需诊断(,因为声明了具有外部链接的标识符,但没有提供定义。您可能看到也可能没有看到错误消息。