2011-06-08 64 views
1

我能想象的静态变量var内部功能func被命名为喜欢[email protected]全局静态/非静态变量如何在c中被破坏?

怎么样全局静态和非静态变量?

+0

您是否检查了装配体? – 2011-06-08 01:45:26

+2

'var @ func'不会是唯一的,除非'func'是外部的......但无论如何,你都离开了。一旦编译器完成它们,非外部变量和函数就不再具有名称。 – 2011-06-08 01:48:00

+0

@R ..对不起,我感到困惑。但是静态变量存储在哪里呢?你说这只是在调试符号表中,我对此怀疑很多。我认为它们应该在用于解析符号的符号表中 – cpuer 2011-06-08 02:52:21

回答

4

编译器不需要使用内部链接来唯一命名事物,如静态变量和函数。您无法访问翻译单元之外的静态对象,因此链接器无需为其获取名称。

具有外部链接的全局变量通常不会在其名称上应用很多变形或修饰,而且通常与应用于函数的变量完全相同。一个领先的下划线并不罕见。

+0

@John Calsbeek,静态变量也在符号表中恢复,所以你必须有一个名字。 – cpuer 2011-06-08 01:37:28

+0

谁的符号表?汇编的? – 2011-06-08 01:41:50

+3

@cpuer:只有调试符号表。它们不存储在用于解析符号的符号表中,因为它们没有任何名称,所以它们没有被破坏。 – 2011-06-08 01:46:35

2

此外,由于这里给出的信息至少不完整。大多数编译器会为静态变量创建“本地”符号,是的,因为函数范围中静态变量的命名不是唯一的,所以它们必须对名称进行修改。 gcc,例如,通过给名称附加一个点和一个唯一编号来实现这一点。由于该点不是任何有效标识符的一部分,因此可以确保没有名称冲突。

当编译器支持标识符中的通用字符时,事情变得模糊。根据环境的不同,编译器必须修改这些标识符,因为例如加载器可能不支持符号表中的这些字符。

icc选择类似于用_uXXXX替换这样的字符,其中XXXX是字符的十六进制表示。在这种情况下(icc)会导致两个微妙的编译器错误。首先,这种修改使用了允许用户使用的有效标识符,因此它们可能会使用来自同一编译单元甚至其他单元的标识符冲突全局符号。其次,icc甚至混合了自己的内部命名,并且只保留一个静态变量的空间,并且如果它们例如也被声明为volatile,则完全暴露无遗。