没被调用的函数与全局变量/静态变量会被编入.out文件吗?

对于函数

自己写的而且没被调用的函数(注意不包括没有specialized的模板),如果不是inline或static,都会被编译,因为编译分两步,首先每个translation unit都会被编译为o file,然后所有o file会被链接成目标文件。而目标文件不一定是可执行程序,也可以是动态链接库,这个时候那些没被用过的函数当然要留下,因为如果是动态链接库那么它在未来任何时候都有可能被另一个程序链接,所以无法判断一个函数是否真的不会再被使用。如果是inline或者static,不用的就会被删除,毕竟在其他translation unit里都不可见,所以删除了不会有任何副作用

实验表明,gcc无论开O3还是Os都不会在最终的可执行程序中删除没被使用的函数。不过,链接器的确有个选项可以删除可执行文件中没被使用的函数(甚至空的section也可以删除),而这些选项可以通过gcc前端传过去。

对于未初始化的全局变量

另外,全局没初始化的非static变量本身不会占据任意大的空间,只会占据一个descriptor,就是可执行文件里bss段多一个记录说明其大小,然后运行时由操作系统分配足够多的空间给该变量并且清零(说明白了,反正都是0,才不会花空间去储存)。全局static变量则因为外部不可见,所以不用的话会被编译器删除。

inline允许同一个函数在多个translation unit里被定义而不会发生链接错误,具体实现是因为inline把函数名标记为weak symbol,链接时weak symbol可以重名。对用户效果就是inline函数可以定义在h文件里。inline本身在函数调用处插入只是个建议,事实上四大主流编译器目前版本没有一个会遵守,你加不加inline,它们都会自己决定是否真的inline。

对于已初始化的非0全局变量

优不优化没有明确规定,不同编译器有不同处理。编译优化也会分级别,gcc -O1(或2),每个优化级别分别做不同的优化;建议查询一下优化级别;
若不用的变量,编译器一般会提示,若能优化则最好,若不会优化会占用内存空间。建议不适用的变量直接删掉;
另外,不建议在函数内定义较大的数组,比如1024 * 1024;因为栈上的空间是有限的,在栈上使用较大的空间会影响程序的运行效率

MDK的处理策略

下面摘自网友:

在使用MDK编写STM32代码时,有些函数如果没用到会报警告:
在这里插入图片描述
函数定义如下:
在这里插入图片描述
但是STM32有很多库函数,为什么没使用到的就不会报警告呢?

这里有一个编译细节,就是函数的有效范围问题。库函数并没有使用static关键字,因为它可能会给其他文件使用,所以编译器会进行全编译,不做整个工程的调用检查,所以也不会报错,但是这样编译出来的HEX文件会大。

而我写的函数明确指定了static,因此编译器缩小了检查范围,因为在该文件中并没有使用到该函数,所以很智能地发出警告,同时不把函数编译进HEX,所以编译出来的HEX会小,虽然有警告,但这是个比较好的编程风格。

以上是出现警告的原因,那有没有方法既缩小HEX,又不报警告呢?

如果坚持要使用比较好的static方式,一定会有警告,没有办法。

要想没有警告,就不能使用static,效仿库函数,MDK编译器提供了一种专门手段用于缩小库函数的,可以借来使用,在编译选项中把”为每个函数生成一个单文件“勾上:
在这里插入图片描述

在勾上它之前:
在这里插入图片描述

勾上它之后:
在这里插入图片描述

可以看出,没用的函数没有被编译进最终的HEX文件,并且不会报错。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值