为什么不同类型的符号占用相同的长度?
Why different type of symbol occupies the same length?
我在 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 binary utilities: nm page:
The symbol value, in the radix selected by options (see below), or
hexadecimal by default. The symbol type. At least the following types
are used; others are, as well, depending on the object file format. If
lowercase, the symbol is usually local; if uppercase, the symbol is
global (external). There are however a few lowercase symbols that are
shown for special global symbols (u, v and w). Depending on pragma
settings and default alignment boundaries, the distance between successive symbol address may be the exact value of the number of bytes for that symbol type
, or it may include padding, which increases the apparent sizeof the symbol.
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 字节。这些大小不会改变,并且不会因将 value 分配给分配给它们的符号而受到影响。
关于内存中各种符号之间的距离space,这个距离既受符号type
影响,又如何aligned along that implementations boundaries, and, as you have noted, compiler: "So it is indeed up to the compiler to decide the padding." Depending on pragma
settings and default alignment boundaries, padding 可能导致连续符号的地址比仅由 type
或 types
的组合 sizeof 值引起的距离更大定义一个特定的符号。 (char
和 struct
类型符号都非常常见)。
我在 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 binary utilities: nm page:
The symbol value, in the radix selected by options (see below), or hexadecimal by default. The symbol type. At least the following types are used; others are, as well, depending on the object file format. If lowercase, the symbol is usually local; if uppercase, the symbol is global (external). There are however a few lowercase symbols that are shown for special global symbols (u, v and w). Depending on
pragma
settings and default alignment boundaries, the distance between successive symbol address may be the exact value of the number of bytes for that symboltype
, or it may include padding, which increases the apparent sizeof the symbol.
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 字节。这些大小不会改变,并且不会因将 value 分配给分配给它们的符号而受到影响。
关于内存中各种符号之间的距离space,这个距离既受符号type
影响,又如何aligned along that implementations boundaries, and, as you have noted, compiler: "So it is indeed up to the compiler to decide the padding." Depending on pragma
settings and default alignment boundaries, padding 可能导致连续符号的地址比仅由 type
或 types
的组合 sizeof 值引起的距离更大定义一个特定的符号。 (char
和 struct
类型符号都非常常见)。