K&R C 变量名

5

我对K&R C中变量名的内容存在一些疑惑。以下是原始文本:

一个内部变量名至少有前31个字符是有效的。对于函数名和外部变量,数字可能少于31个,因为组装程序和加载器可以使用外部名称,而这些程序不受语言的控制。对于外部名称,标准仅保证唯一性的6个字符和单个大小写。像if,else,int,float等关键字是预留的:您不能将它们用作变量名。它们必须是小写的。 最好选择与变量用途相关且不易出现排版混淆的变量名。我们倾向于使用短名称表示局部变量,特别是循环索引,而对于外部变量则使用较长的名称。

让我困惑的是外部名称,标准仅保证唯一性的6个字符和单个大小写。这是否意味着对于外部名称,只有前6个字符是有效的,其余的字符都被忽略了?例如,我们定义了两个外部变量myexvar1和myexvar2,编译器会将这两个变量视为一个吗?如果是这样,为什么他们建议我们在外部变量中使用更长的名称?


10
2019年,人们可能需要关注的标准是C11,因此请阅读n1570。在今天的大多数实现中,外部名称中的所有字符实际上都是重要的。在我的Linux系统上,仅出于好奇,我尝试使用了一个有一百万个字母的符号。实际上,它们全部都是重要的。 - Basile Starynkevitch
2
我理解的是,“外部变量使用更长的名称”与“本地变量,特别是循环索引使用短名称”形成对比。因此,例如,您的迭代器将具有像i这样的名称,而外部变量将具有比此更长的名称。 - Blaze
请注意,外部变量可能不是来自不同的工具链,而是绑定在相同规则下的不同C模块。 - Weather Vane
4个回答

7
这是否意味着外部名称仅使用前6个字符是有效的,其余字符都被忽略了?例如,我们定义了两个外部变量myexvar1和myexvar2,编译器将把这两个变量视为一个吗?
是的,在1990年确实如此。或者说,C90标准将6个唯一的前导字符作为编译器的最小限制。这当然是疯狂的 - 这就是为什么在C99中将此限制增加到31的原因。
实际上,大多数C90编译器对内部和外部标识符都有至少31个唯一字符。
如果这是真的,为什么他们建议我们使用更长的名称来表示外部变量?
不确定他们是否建议。但是,K&R中使用的编码风格通常很糟糕,因此它绝对不是您应该咨询编码风格建议的书籍。
在现代C中,需要(C17 5.2.4.1):
64位内部标识符或宏名称的重要初始字符
31个重要的外部标识符的初始字符
因此,不要过于担心恐龙面临的限制,而是遵循现代标准C。
正如另一个答案所指出的那样,即使是外部标识符的31个重要初始字符的限制也被列为过时,这意味着在未来的标准中可能会进一步增加到255。

2
说实话,K&R相当古老,所以我认为事情自那时以来已经发生了变化。 我真的不知道他们在这里为什么要给出确切的6个字符:
对于外部名称,标准仅保证唯一性为6个字符和单个大小写。
但你必须明白,编译器所做的只是将翻译单元(通常是一个*.c文件)转换成一个目标文件(*.o)。就是这样。编译器不会生成一个可运行的程序。
这些目标文件可能包含对未解析符号的引用,这些符号可以在其他目标文件中找到,以及它们自己的外部符号表,它们提供要从外部引用的符号。符号具有文本名称,这些名称是您赋予外部变量的名称。
链接器和动态加载器仍然需要完成它们的工作来构建程序并使其运行。在此过程中,它们必须解决所有未解决的符号,因此它们执行文本查找以查找对象文件中的这些符号。链接器和加载器不是编译器。它们可能有关于处理这些名称的自己的规则(我猜在K&R时代)。这就是这个...的意思
因为外部名称可能被汇编器和装载器使用,而语言无法控制。
这就是这个问题的原因。
但是现在,你所关心的K&R都已经过时和不相关了。选择一个更新的标准进行遵循。

2
这是由于涉及到系统链接器中导出符号的长度的历史背景造成的。
我引用了《新C标准——经济和文化评论》中的一段话。
"6"和"10"的值是为了可以使用编码\u1234和\U12345678。Fortran的六个重要字符限制在很长一段时间内被许多链接器供应商所遵循。支持C++名称修饰需要更长的标识符,这确保了大多数现代链接器支持更多外部标识符中的重要字符。历史上,外部标识符中的重要字符数量取决于主机供应商提供的链接器的行为。只有自MS-DOS以来,开发人员才习惯于翻译供应商提供自己的链接器。以前,大多数链接器往往由硬件供应商提供。大型机世界往往受到Fortran的要求驱动,其中内部或外部标识符有六个重要字符。在这种环境下,不总是可能用支持更多重要字符的链接器替换系统链接器。20世纪90年代,大型机环境的重要性减弱了。在现代环境中,往往可以获得替代链接器。

因此,主要问题是能够将在C中编译的库与在Fortran中编译的库链接在一起,而Fortran则施加了6的限制。
您可以在给定的参考资料中阅读更多信息。

0

这是过去的遗留问题,现在已经不再重要了。现在的编译器都没有这些限制,这些限制来自于旧版Unix的时代。当时和现在的原因都是编译器对符号表中名称的限制(31个字符)以及链接器使用的限制(6个字符)。

但这已经不适用了。至少你可以确定今天的链接器将允许不同的标识符以至少100个字符的公共前缀来表示不同的内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接