gpt4 book ai didi

c - GCC 中静态变量的符号是如何命名的?

转载 作者:行者123 更新时间:2023-12-02 09:07:19 25 4
gpt4 key购买 nike

我正在 C 中试验静态全局变量。我尝试了这段代码并在其上运行了 nm:

#include <stdio.h>

static int global_static = 12345;

int main(void)
{
static int local_static = 12345;
printf("%d\n", global_static);
printf("%d\n", local_static);
return 0;
}

这是 nm 输出的片段:

00004020 d global_static
00004024 d local_static.1905
000011a9 T main

我有两个问题:

  • 局部静态变量的名称从何而来?是进程ID还是随机数?

  • global_static 中没有无效字符这一事实是否意味着我可以在另一个文件中执行 extern static int global_static; 并读取 global_static ?

当我说无效字符时,我指的是不能作为 C 变量名一部分的字符,即 .$% #

最佳答案

Where does the name for the local static variable come from? Is it a process ID or a random number?

在gcc的langhooks.c中,默认的set_decl_assembler_name钩子(Hook)实现(C语言直接使用)contains :

  /* By default, assume the name to use in assembly code is the same
as that used in the source language. (That's correct for C, and
GCC used to set DECL_ASSEMBLER_NAME to the same value as
DECL_NAME in build_decl, so this choice provides backwards
compatibility with existing front-ends. This assumption is wrapped
in a target hook, to allow for target-specific modification of the
identifier.
Can't use just the variable's own name for a variable whose scope
is less than the whole compilation. Concatenate a distinguishing
number - we use the DECL_UID. */
if (TREE_PUBLIC (decl) || DECL_FILE_SCOPE_P (decl))
id = targetm.mangle_decl_assembler_name (decl, DECL_NAME (decl));
else
{
const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
char *label;
ASM_FORMAT_PRIVATE_NAME (label, name, DECL_UID (decl));
id = get_identifier (label);
}

还有 comment on the macro DECL_UID说:

/* Every ..._DECL node gets a unique number.  */

所以这个数字是 gcc 发明的一些标识符,保证在翻译单元中看到的每个声明都是不同的(包括 #include-d 文件中的声明)。这足以确保如果不同的范围使用具有相同名称的局部静态变量,它们在汇编代码和目标代码中将具有不同的错位符号名称。

Does the fact that global_static has no invalid characters in it imply that I could do extern static int global_static; in another file and read global_static?

没有。一方面,将 externstatic 结合使用是非法的,因为它们会给变量提供相互冲突的链接。请注意,static 在 C 中有两个完全不同的含义:在函数内部,它表示变量具有静态存储持续时间。在函数外部,表示变量或函数具有内部链接。 (不是函数本地的变量始终具有静态存储持续时间。)

所以从 C 语言的角度来看,global_static 上的 static 意味着该变量具有内部链接,这意味着它永远不会被视为与任何其他翻译单元中的任何内容,因此无法从另一个 *.c 文件直接访问它。当转换为 ELF 对象或其他常见对象格式时,这是通过使变量的符号成为“本地”符号而不是“全局”符号来完成的。当链接可执行文件或加载动态库时,全局符号可以满足来自另一个对象的 undefined symbol ,但局部符号永远不会。

注意 nm 工具为全局符号打印大写符号类型字母,为局部符号打印小写符号类型字母,因此输出中变量旁边的 d 表示两者都是本地符号,不可能被其他对象直接使用。

关于c - GCC 中静态变量的符号是如何命名的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56498960/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com