关于 c 的一个问题不理解

2019-07-29 11:10:22 +08:00
 fvckDaybyte2
环境:最新 mac os 以及自带的 gcc 环境
如下代码中有一个全局变量 int a[30]
'''
#include <stdio.h>
int a[30];
int main() {
printf("hello world");
}
'''
如果吧 int a[30]; 注释掉,编译后可执行文件的大小是 8432byte ;
如果不注释,可执行文件大小是 8456byte ;
如果改成 int a[30]={1,2,3...30};,可执行文件大小依然是 8456byte ;
已知 int 的在 mac 下大小是 4byte,int[30]的大小应该是 120byte,为何后两种情况可执行文件只增加了 24byte ? a 是记录在 data 段还是 bss 段?
谢谢解答
2792 次点击
所在节点    程序员
26 条回复
ShangShanXiaShan
2019-07-29 11:34:03 +08:00
未初始化的全局变量放在 bss
wangyaominde
2019-07-29 11:58:53 +08:00
生成文件的大小难道不是生成的机器码的大小吗?
BingoXuan
2019-07-29 12:02:12 +08:00
应该是编译器做了优化吧
zealot0630
2019-07-29 12:06:26 +08:00
objdump -t ./a.out 会告诉你答案
wangyaominde
2019-07-29 12:07:23 +08:00
https://i.loli.net/2019/07/29/5d3e6fc3702bc64628.png
左侧是未注释的,汇编就差一句
https://i.loli.net/2019/07/29/5d3e70930490b24948.png
这个是 int a[30]={1,2,3...30};的,之前遇到过编译器自作聪明删掉变量的。。。。猜测跟编译器相关。
zealot0630
2019-07-29 12:07:28 +08:00
配合 objdump -h 食用
VDimos
2019-07-29 12:11:13 +08:00
文件大小和 has data ?
iAcn
2019-07-29 12:11:34 +08:00
编译器把未使用的全局变量删了吧。
menyakun
2019-07-29 13:27:44 +08:00
对于链接后的可执行文件来说,各个 section 之间是有很多 gap 的。你按数据大小来算文件大小,对比链接前的目标文件的话会更有可比性一点
takeoffyoung
2019-07-29 13:32:12 +08:00
代码编译之后可执行文件占用磁盘的大小和代码运行时占用内存的大小有啥关系呢。
总不能说你的代码里面声明了一个占内存 10 个 G 的变量,你编译的可执行文件会占用 10 个 G 的磁盘空间?
zyp0921
2019-07-29 13:41:09 +08:00
可以去看看程序员的自我修养这本书。。。强力推荐哟
johnkiller
2019-07-29 13:53:44 +08:00
@takeoffyoung 正解
kljsandjb
2019-07-29 13:58:18 +08:00
机器码啊,你比较一下,指令都是编码成二进制的
johnkiller
2019-07-29 14:00:53 +08:00
int a[100];

int a[999];

文件占用肯定都一样,

我觉得文件的大小与生成的汇编语句量有关,而不是变量的大小啊,变量跟内存才有关

个人理解,接受指正
season4675
2019-07-29 14:05:32 +08:00
你这是内存使用情况啊,和文件大小没关系啊……
johnkiller
2019-07-29 14:06:14 +08:00
1. malloc int, 100
2. malloc flt, 999

抽象描述大概应该就是这个意思,字符长度都一样,但是运行时内存占用不一样
menyakun
2019-07-29 14:08:58 +08:00
@takeoffyoung 如果你声明并初始化了一个占 10 个 G 的全局变量或这 static 变量的话,编译后的文件的确会占 10 多个 G
takeoffyoung
2019-07-29 14:20:24 +08:00
@menyakun 并不会,除非你的初始化是用相等长度的代码来实现的。这两者就是没有关系,如果在代码中用写下一千万个数字来初始化长度为一千万的数字。这种方式导致的可执行文件的大小的变化,并不能归纳到你的结论上。
Nitroethane
2019-07-29 14:22:36 +08:00
@ShangShanXiaShan 一楼正解
menyakun
2019-07-29 14:30:14 +08:00
@takeoffyoung 不是这个道理,就算再大的数组,只要有一个成员被初始化了,那么其他的文件就可以修改这个数组里的值,所以这个数组必须在链接时就被初始化,这样涉及到这个数组的汇编才能生成。重申一下,这里说的都是全局变量和局部静态变量。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/587075

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX