【发布时间】:2018-04-26 13:55:05
【问题描述】:
我在 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 个字节。所以实际上由编译器决定填充。
【问题讨论】:
-
地址没有告诉你任何关于尺寸的信息。
-
主要做:
printf("%zu %zu", sizeof(mango), sizeof(melon)); -
@smwikipedia 这可能是地址。我们所说的是地址并没有告诉你大小。
melon可能必须位于 8 字节边界上,因此在变量之间添加了填充。但是编译器可以在这里为所欲为。 -
请记住,编译器会在不同的边界上对齐事物并根据需要添加填充。所以在
char的情况下可能有 1 个字节大小,7 个字节填充。使用sizeof确定大小。 -
"所以
mango的地址是100402010。而melon的地址是100402018。所以mango应该占用8个字节。" --不,这意味着mango使用不超过 8 个字节。出于性能原因(由硬件强加),这些值以处理器字的长度对齐存储在内存中。对于 64 位处理器,任何值的内存地址都是 8 字节的倍数(即 64 位)。可以告诉编译器使用不同的对齐方式,但您应该有充分的理由这样做。
标签: c object-files nm