大多数C语言(或与此相关的任何语言)的关键字都以字母开头。但是有些关键字以下划线开头吗?它们的关键字是:sum
,teamDbRef = db.collection('teams').doc('CnbasS9cZQ2SfvGY2r3b'); /* CnbasS9cZQ2SfvGY2r3b being the collection ID */
//
//
db.collection("squad").where('team', '==', teamDbRef).get().then((querySnapshot) => {
//
}).catch(function(error) {
//
});
,_Alignas
,_Alignof
,_Atomic
,_Bool
,_Complex
,{{1} },_Generic
和_Imaginary
。
我觉得这很奇怪。如果它是不是API真正组成部分的隐藏的全局常量或内部函数,我会理解的。但是这些是关键字。
当C实际上有一个名为_Noreturn
和_Static_assert
的宏,并且它们的实现使用关键字时,我感到特别奇怪。
答案 0 :(得分:7)
C在标准委员会计划之前已经发展并非常受欢迎。结果,现有的代码很多。
设置C标准或更新旧标准时,一个重要的目标不是“破坏”旧代码。希望与以前的编译器一起使用的代码继续与新版本的C语言一起使用。
引入新的关键字(或单词的任何新定义或含义)可能会破坏旧代码,因为在编译时,该单词将具有其新关键字含义,而不是先前编译器具有的标识符含义。该代码将必须进行编辑。除了要花钱去编辑代码之外,如果有任何错误,这也有引入错误的风险。
为解决这个问题,制定了一个规则,即保留以下划线开头的标识符。制定此规则并不会破坏很多旧软件,因为大多数编写软件的人都选择使用以字母开头而不是下划线的标识符。该规则为C标准提供了一项新功能:只要在单词中添加下划线或其他新含义时使用下划线,就可以在不破坏旧代码的情况下做到这一点,只要该旧代码遵守该规则即可。
C标准的新版本有时会为不以下划线开头的单词引入新的含义,例如bool
。但是,这些新含义通常不会在核心语言中引入。相反,它们仅在新的头文件中引入。在创建bool
类型时,C标准提供了一个新的头文件<stdbool.h>
。由于旧代码无法包含<stdbool.h>
,因为它在编写代码时不存在,因此在bool
中定义<stdbool.h>
不会破坏旧代码。同时,它通过包含bool
使编写新代码的程序员能够使用新的<stdbool.h>
功能。
答案 1 :(得分:5)
在标准中,保留以双下划线或下划线开头并以大写字母开头的任何名称。这很有用,因为C缺少命名空间。通过保留所有这些符号,可以将新的和特定于实现的关键字引入该语言,而不会与现有代码中定义的符号冲突。
bool
和static_assert
之类的宏是“ 便利宏”,它们使您可以使用保留的关键字符号而无需使用下划线和大写字母,冒着很小的风险。名称冲突。但是,它们提供了一种解决名称冲突的方法,因为与关键字不同,可以插入#undef
宏,或者排除定义它的标头和直接使用内部关键字。此外,未修改的旧代码不会被破坏,因为根据定义,它将不包含编写时不存在的标头
自该语言创建以来,就已经在该语言中定义了未经修饰的关键字(自C99以来定义的inline
和restrict
除外),因此不会与传统代码符号产生冲突。所有_Xxxx
关键字都已在C99或之后定义。
与当今许多常用语言不同,C语言自1970年代就出现了,并自1989年开始标准化-有大量现有代码必须在现代编译器上可编译,而同时该语言不能保持不变-如果它确实不再使用了。
答案 2 :(得分:1)
埃里克(Eric)和克利福德(Clifford)提供了很好的答案,但是我添加了C11标准的引用来支持它。
- 所有以下划线开头,大写字母或另一个下划线开头的标识符始终保留用于任何用途。
- 所有以下划线开头的标识符始终保留用作普通和标记名称空间中文件范围的标识符。
https://port70.net/~nsz/c/c11/n1570.html#7.1.3
人们可能还会考虑:
以int或uint开头并以_t结尾的Typedef名称可以添加到stdint.h标头中定义的类型中。可以将以INT或UINT开头并以_MAX,_MIN或_C结尾的宏名称添加到stdint.h标头中定义的宏。