(K&R) 内部名称的前31个字符至少是有意义的?

18

字面上理解是有意义的,但是什么是变量名的显著字符呢?

我学习C语言使用K&R,这是书中的直接引用:

“至少前31个字符是内部名称中的显著字符。对于函数名和外部变量,该数字可能小于31,因为外部名称可能被汇编程序和加载器使用,而语言无法控制。对于外部名称,标准只保证了6个字符和一个大小写。”

顺便问一下,“单个情况”是什么意思?


如果你刚开始学习C语言,为什么想要了解K&R? Ansi C89/99更加“理智”和流行。 - Earlz
我不确定应该买哪本书来学习C语言。有人告诉我K&R可以完美地教我如何编写C程序,但是到目前为止,有时候它似乎有点难以理解。它似乎有点模糊,充满简洁和高级术语。然而,我可能是错的... - withchemicals
3
“K&R C”是第一版K&R书介绍的原始C方言,现在已经过时。我希望(并且希望!)您实际上有K&R的第二版,它涵盖了ANSI C。这是一本很棒的书,但自那时以来ANSI C标准已经有了进一步的发布。变化并不是很大,但值得了解。现在你可以获得一些新类型,如布尔和长长整型,而且,是的,疯狂的短标识符限制已经大大提高。 - bobince
是的,我有覆盖 ANSI C 的 K&R 第二版。有趣的是,我在不完全理解 ANSI C 是什么的情况下就开始阅读了这本书。据我所知,它仅是一种编写代码的标准方法,以便任何了解 ANSI 标准的人都能理解上述代码(希望我的理解是正确的)。这类似于中国讲很多方言,但普通话是官方语言(?)。出于好奇,如果 C 代码不符合 ANSI 标准,它是否仍然可以编译? - withchemicals
2
ANSI标准定义了特定版本的C语言是什么。每个编译器决定如何处理不符合标准的代码。大多数(全部?)编译器都支持一些扩展。如果一个特定的程序不符合标准,那么它是否应该被称为“C”是有争议的,例如“GNU C”或“带有某些扩展的C”。 - Steve Jessop
5个回答

21

单个字母大小写通常指小写,但在某些操作系统中可能指大写。重点是混合大小写不能保证可用。

abcdef

ABCDEF

这两个字符串仅在大小写上有所不同。但这并不能保证可行。

“Significance”问题涉及相同的字母数量。

假设我们只有6个有效字符。

a_very_long_name

a_very_long_name_thats_too_similar

看起来不同,但前16个字符是相同的。由于只有6个字符是重要的,因此它们是同一个变量。


1
你真是太棒了!所以只是确认一下,这个引用:“对于外部名称,标准仅保证6个字符和单个大小写。”是不是意味着AbCDeF、abcdef和ABCDEF都不能100%保证是不同的变量?此外,作为初学者程序员,我应该担心所提到的“汇编器和加载程序”吗? - withchemicals
2
正确。仅由大小写区分的事物不能保证有效。它们可能有效,但那只是偶然。您不会很快使用汇编器。您的加载程序是操作系统的一部分。大多数加载程序处理非常长的名称。当我还是80年代的新手程序员时,对于某些操作系统来说,6个字符的限制是严重的问题。对于标准操作系统(Linux、MacOS等),不用担心。对于Windows,几乎没有问题。 - S.Lott

7
这意味着你所担心的那样。对于外部名称,在K&R第二版编写时,C标准确实只给出了六个不区分大小写的字符!因此,您不能将afoobaraFooBaz视为独立的实体。
这种荒谬的限制(旨在适应现在已经消失的传统链接器)对任何环境都不再相关。 C99标准为外部名称提供31个区分大小写的字符和63个内部字符,并且实际上常用的链接器支持更长的名称。

3

这只是意味着如果你有两个变量名为

abcdefghijklmnopqrstuvwxyz78901A

abcdefghijklmnopqrstuvwxyz78901B

那么不能保证它们会被视为不同的、独立的变量...


2
这意味着:
foobar1
foobar2

可能会有相同的外部名称,因为只需要考虑前6个字符。单一情况意味着不必区分大小写名称。

请注意,几乎所有现代链接器都会考虑更长的名称,尽管仍然存在一个取决于链接器的限制。


0

你好,

这种有限符号解析的问题之一出现在链接时。

同名的多个符号可能存在于几个库中,链接编辑器通常只会选择它找到的第一个与其寻找的匹配项相匹配的符号。

因此,使用上面S.Lott的例子,如果您的链接编辑器正在搜索符号“a_very_long_name”,并且它发现了一个包含符号“a_very_long_name_thats_too_similar”的库,它将选择后者。即使包含您想要的符号的库,即“a_very_long_name”已在命令中指定。例如,指定库为:

-L/my/library/path -lmy_wrong_lib -lmy_correct_lib

现在有编译器选项,或更准确地说是编译时选项,这些选项通过链接编辑器传递,强制在您的链接路径中搜索多个符号。然后通常会在链接时将它们作为错误引发。

此外,许多编译器(例如gcc)将默认采用这种行为。您必须明确启用多个定义,以允许链接编辑器在找到符号的多个定义时继续进行而不引发致命错误。

顺便说一句,我强烈建议与Clovis Tondo的书“The C Answer Book 2nd ed.”一起完成练习。

这样做真的有助于让C语言深入人心。

希望对你有所帮助。

祝好,


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