程序只能在O0下运行,O1/O2/O3优化会hang/segment fault

尝试了挺久才解决的,简单记录下过程中的一些思考:

现象:

程序hang/segment_fault的位置都是在同一个位置:一个lambda函数(会被注册为一个回调函数来使用), 类型大致是这样(有纯虚函数定义了回调函数的类型)

auto f = [&] () -> bool {
	//some operation
	//no return statement.
};

因为在编译的时候使用-Wp,-w, 这个选项会关闭预处理过程中的所有warning, 所以即使没有return语句也没有报错(程序在编译的时候是使用了-Wall的)

尝试:

  1. 既然O0是可以运行的,所以程序来逻辑/语法上肯定是没有问题的,所以就想着先把lambda函数关闭优化,可以使用__attribute__((optimize(“O0”))), 但问题在于我把这句挡在->bool之前的话会报错,所以我就试着把->bool给删除掉,然后在{}内显示的写了return true,函数调用处并不会使用这个return的值,所以return true/false倒无所谓。编译、运行,发现可以pass test。
    1.1 试图查阅在lambda表达式中__attribute__应该放的位置,没找到。所以才投机取巧把->bool删除掉了。
  2. 进而我猜测不会是因为return语句导致的吧?于是就又把__attribute__((optimize(“O0”)))删掉,->bool加回来,然后return true, 编译、运行,test pass。

结论

其实没什么结论,也不理解为什么一个return语句会产生这样的问题,但给我的启示是:

  1. code要标准,要严格按照规范来,该return就return,就能减少遇到类似的问题。
  2. 要重视Warnings。这次遇到是因为Makefile从别的port过来的时候带了-Wp,-w, 把预处理器所有的Warning给关掉了。

更新01:

经过查阅资料,理解了为什么缺少return语句会产生这样的问题:
函数缺少 return 语句会导致未定义行为(undefined behavior,UB),这不仅会引发程序运行时的错误,还会影响编译器的优化过程。编译器在优化代码时,会基于一些假设进行,例如所有函数都按照其声明的返回类型返回值。如果某个函数缺少 return 语句,编译器的这些假设就会被打破,从而导致不可预测的行为。

  • 当函数缺少 return 语句时,编译器可能会认为某些代码路径是不可达的(unreachable)。例如,GCC和Clang编译器会在这种情况下插入 __builtin_unreachable(),这会标记代码路径为不可达。
  • 在优化过程中,编译器可能会移除这些不可达的代码路径,从而导致程序在运行时出现意外的行为。

并且,务必注意,不可预测的行为是指无法预测接下来会发生什么(而不是通常意义上的简单理解为返回随机值)。

参考:An example of undefined behavior caused by absence of return

扩展阅读:

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值