小心 UB

记录一下这次由于眼睛瞎了“学习” DPDK 的 lockfree ring 来改装自己的 spsc lockfree ring 的时候选择性忽视了 volatile。

2021/12/3 10:57

我不知道什么时候引发一个印象是因为清楚了编译器的代码优化工作之后形成一种观念是 inline register 这些 qualifier 都没用,结果无意识下也把 volatile 给算进去了。

但是肯定不能这样想啊,毕竟 cv qualifier 每次写相关的东西都会有 clang-tidy 或者 ide 提醒的警告或者报错说 casting 的时候把 cv qualifier 给做掉是不对的。

由于 benchmark 肯定要在 O2 下才能对比,这个 bug 在我的 spsc ring 里面一直没 de 出来,就是开 O2 和 不 开 O2 的结果竟然不一样,当时就把我震惊了。本着肯定是自己错了遗漏了什么而不可能是 O2 的 bug 。。。然而我还是没有抛弃 volatile 没有这个观念,压根没往那边想,回去看 dpdk 的源码也是揪着那里 unsigned wrap around 想找到问题所在。。。故事再一次证明了我之前想到的凡是对比错误一定要逐行对比,从 ADT 定义到逻辑,这次又没有做到。。下次一定。

当然我自己也想去看汇编,毕竟学了汇编。结果搞了一个小时还是没找到正常生成多文件的 interleaf 的 c++ code + assembly code 方法,而单个文件又没办法把 spsc ring 头文件的模板 inline 函数给编出来,所以我绷不住了。

然后才想到要去除无关的东西复现问题,才想到复现问题的第一步应该是写 minimal reproducible example,这样汇编的问题也解决了,毕竟这种单文件的小代码直接 g++ -S 然后 objdump 就行了。不过邻近上课时间了,为了5分钟杀到教室,我也不汇编了,最小代码跑出来 O2 不同结果了马上就 post 了一个问题(当然还是以为问题在 unsigned wrap around 上,我以为他 wrap 失败了,就算我以及查过资料确定了这个是 well-defined 的,只能说我的思维定势太严重了,实在不太行)。

结果我写出了这种东西来,然后提问了一下(低水平问题了属于是):

c++ - Why g++ O==2 option make unsigned wrap around not working? - Stack Overflow

(实际给的 minimal reproducible example 因为急着上课写得 pop 忘记判断是否能 pop 了。。。 )

总结一下就是 UB 有危害吧。(没想过 infinite loop without side effect 这个反而也是问题,所以导致 minimal example 的结果其实也和 spsc ring 的bug 不一样,只能说变量实在是太多了)。

cv qualifier 很重要。

附上复习资料:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值