y = 4; &y在编译器的符号表中是否有名称?

时间:2018-10-21 22:48:33

标签: c

我创建了一段代码来测试直接变量和间接变量(指针)

#include <stdio.h>
int x = 3;
int y = 4;

int main(void)
{   
    int *pointer;
    *pointer = x;

    printf("x's address is %p, x's value is %d.\n",pointer, *pointer);
    printf("y's address is %p, x's value is %d.\n",&y, y);
    return 0;
}

它输出

$ ./a.out
x's address is 0x7ffee1b2d6d8, x's value is 3.
y's address is 0x10e0d301c, x's value is 4.

我可以看到x的地址存储在另一个内存块中,该内存块在编译器符号表中被称为指针作为变量,
&y怎么样,
y的地址可以由&y检索,后者将内存块放在某个地方。&y在编译器的符号表中是否有名称。

2 个答案:

答案 0 :(得分:2)

首先,以下内容不正确:

int *pointer;
*pointer = x;

pointer未初始化,但是您要取消引用并存储x。您可能打算分配x的地址,即int *pointer = &x;

要回答是,xy都最有可能使用单独的符号。您可以使用readelf之类的工具(在GNU系统上)进行验证:

readelf -Ws a.out

将显示符号,您可以查找xy

请注意,符号和符号表等详细信息不在C标准(未指定/定义)的范围内。因此,这可能会因系统而异。

除遵守该标准外,只要遵守observed behaviour(也称为“假设规则”),标准编译器就可以生成代码,这意味着在生成的代码中不一定总是存在“变量”因为编译器通常会消除它们(或将它们放入寄存器)。

P.S:要打印地址,您需要按照格式说明符void*的要求将其强制转换为%p

printf("x's address is %p, x's value is %d.\n", (void*)pointer, *pointer);
printf("y's address is %p, y's value is %d.\n", (void*)&y, y);

答案 1 :(得分:1)

在源代码中使用&y时,编译器不需要创建新对象来存储y的地址。

符号表中的条目实际上是xy的位置。 (条目通常不是完整的地址,但通常是相对于符号所在部分的偏移量。)

因此,当使用&y时,编译器将在生成的汇编代码中插入对y的引用。链接器和/或加载器使用y的地址填充此引用。

[以上内容当然不是C标准的一部分。通常只有编译器,链接器和加载器才起作用。]