如何强制GCC将所有代码放在函数序言与尾声之间,避免ret指令后存在代码
GCC 实现方案
- 核心方案是关闭基本块重排优化,使用编译选项
-fno-reorder-blocks即可。该选项仅禁止GCC将不常执行的冷基本块重排到函数尾声的ret指令之后,不会影响其他O1/O2/Os级别的优化效果,几乎不会带来额外的性能损失,可以完美替代-O0实现你的需求。 - 如果不需要全局生效,仅针对特定函数关闭块重排,可以给函数添加属性声明:
__attribute__((optimize("no-reorder-blocks"))) void foo(int a) { // 函数实现 }
- 若使用高版本GCC且开启了激进的函数分区优化,可额外添加
-fno-reorder-blocks-and-partition选项,禁止GCC将函数拆分为冷热分区,避免冷代码块被放到整个文本段的其他位置。
其他编译器对应选项
- Clang/LLVM:使用
-fno-block-placement选项关闭基本块重排,单个函数可以使用__attribute__((clang::optimize("no-block-placement")))做精准控制。 - MSVC:使用
/d2::no-block-layout选项关闭编译器的基本块布局重排逻辑,避免冷块被移动到函数尾部之外。
如果你的使用场景是需要做函数完整性校验、热补丁等对函数代码块连续性有要求的场景,还可以额外添加 -fno-jump-tables 选项,避免switch语句的跳转表被插入到代码段的非指令区域。
内容的提问来源于stack exchange,提问作者tach
相关产品推荐
相关产品推荐

