我在x64机器上用cygwin GCC编译了下面的代码:
gcc main.c -o main
(main.c(
long long mango = 13; // I also tried `char`, `short`, `int`
long melon = 2001;
void main()
{
}
然后,我将符号值转储给nm
:
./main:0000000100402010 D mango
./main:0000000100402018 D melon
我了解,符号的价值仅表示其地址。因此mango
的地址是100402010
。和melon
具有地址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个字节。因此,确实取决于编译器来决定填充。
来自 gnu nm二进制实用程序:nm page :
符号值,在选项选择的radix中(见下文(或 默认情况下,十六进制。符号类型。至少以下类型 被使用;其他的也取决于对象文件格式。如果 小写,符号通常是本地的;如果大写,则符号是 全局(外部(。但是有一些小写的符号 显示特殊的全局符号(U,V和W(。取决于
pragma
设置和默认对齐边界,连续符号地址之间的距离可能是该符号type
的字节数的确切值,或者可能包括 padding ,这增加了明显的大小符号。
A
The symbol’s value is absolute, and will not be changed by further linking.
B
...
imo在nm
中使用单词 value 是不幸的,因为在此上下文中, value 用于描述符号的地址。符号(值(的地址不会更改。但是在正常的c说话中,符号的 value 确实会改变:
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个字节。这些尺寸不会改变,也不会通过将A value 分配给分配给它们的符号来影响。
关于在各种符号之间发生的内存空间距离,此距离都受符号的type
的影响,沿该实现边界如何对齐,如您所指出的那样,:"因此,确实取决于编译器来决定填充。" 取决于pragma
设置和默认对齐边界, padding 可能会导致连续符号的地址为一个比仅由type
的组合 sizeof 值或定义特定符号的types
引起的距离更大。(char
和struct
类型符号都非常常见(。