C 为什么不同类型的符号占用相同的长度?

C 为什么不同类型的符号占用相同的长度?,c,object-files,nm,C,Object Files,Nm,我在x64机器上使用cygwin GCC编译了以下代码: gcc main.c -o main (main.c) 然后我用nm转储符号值: ./main:0000000100402010 D mango ./main:0000000100402018 D melon 据我所知,一个符号的价值仅仅意味着它的地址。所以mango的地址是100402010。而且瓜有地址100402018。所以mango应该占用8个字节 我尝试了其他类型的mango,比如char,int,short。它总是占用8个

我在x64机器上使用cygwin GCC编译了以下代码:

gcc main.c -o main
(main.c)

然后我用
nm
转储符号值:

./main:0000000100402010 D mango
./main:0000000100402018 D melon
据我所知,一个符号的价值仅仅意味着它的地址。所以
mango
的地址是
100402010
。而且
有地址
100402018
。所以
mango
应该占用8个字节

我尝试了其他类型的
mango
,比如
char
int
short
。它总是占用8个字节

为什么尺寸不变

加1 谢谢你的评论

我刚刚尝试了以下代码:

typedef struct{
    char a1;
    char a2;
    char a3;
    char a4;
    char a5;
} MyStruct;

MyStruct MyObj1={1,2,3,4,5};

MyStruct MyObj2={1,2,3,4,5};

long long mango = 13;
long melon = 2001;

void main()
{

}
这一次,
nm
向我展示了:

./main:0000000100402020 D mango
./main:0000000100402028 D melon
./main:0000000100402010 D MyObj1
./main:0000000100402015 D MyObj2
MyObj1
MyObj2
是5个字节分隔的。因此,确实是由编译器来决定填充。

来自:

符号值,以选项选择的基数表示(见下文),或 默认情况下为十六进制。符号类型。至少以下类型 使用;其他也取决于对象文件格式。如果 小写,符号通常是本地的;如果为大写,则符号为 全球(外部)。但是,有一些小写符号是 显示特殊全局符号(u、v和w)。根据
pragma
设置和默认对齐边界,连续符号地址之间的距离可能是该符号
类型
的字节数的精确值,也可能包括,这会增加符号的外观大小

在我看来,在
nm
术语中使用value一词是不幸的,因为在此上下文中,value用于描述符号的地址。符号(值)的地址不会更改。但在正常的C语言中,符号的值会发生变化,例如:

int i = 0; // the address for symbol i will remain constant
i = 10;    // but the value of the symbol i can change. 
关于地址的大小,64位构建的任何符号的地址将始终具有8字节的大小,而32位构建的任何符号的地址将具有4字节的大小。这些尺寸不会更改,并且不会因为指定给它们的符号指定值而受到影响


关于不同符号之间的内存空间距离,这种距离既受符号的
类型
的影响,也受实现边界的影响,正如您所指出的,还受编译器的影响:“因此,确实由编译器决定填充。”根据
pragma
设置和默认对齐边界,可能导致连续符号的地址距离大于仅由定义特定符号的
类型或
类型的组合大小值引起的距离。(对于
char
struct
类型符号,这是非常常见的情况)

该地址没有告诉您任何有关大小的信息。在main do:
printf(“%zu%zu”、sizeof(mango)、sizeof(甜瓜))@smwikipedia可能就是这个地址。我们要说的是地址没有告诉你大小。有可能
必须在8字节边界上,因此在变量之间添加了填充。但是编译器可以在这里做任何它想做的事情。请记住,编译器将在不同的边界上对齐内容,并根据需要添加填充。因此,如果是
char
,则可能有1字节大小,7字节填充。使用
sizeof
来确定大小。“因此
mango
的地址是
100402010
wall
的地址是
100402018
。因此
mango
应该占用8个字节。”——不,这意味着
mango
使用的字节不超过8个。出于性能原因(由硬件强制),这些值存储在内存中,以处理器字的长度对齐。对于64位处理器,任何值的内存地址都是8字节(即64位)的倍数。可以告诉编译器使用不同的对齐方式,但您应该有充分的理由这样做。谢谢。我同意你的观点,nm术语中的“价值”一词是不幸的。
A

    The symbol’s value is absolute, and will not be changed by further linking.
B
...
int i = 0; // the address for symbol i will remain constant
i = 10;    // but the value of the symbol i can change.