发布于 ,更新于 

❎ 一次与 C++ 未定义行为的斗智斗勇

Kvantum 是一个 Qt 主题引擎,可以用 SVG 方便地制作 Qt / KDE 主题,深受用户喜爱。大多数的 KDE 主题都使用了 Kvantum。

Kvantum 三年来在我主力电脑(x86_64)的 Arch Linux 系统上一直工作良好,但今年六月我购入了一台 arm64 的平板电脑并刷入 Arch Linux ARM 系统随身携带使用,在它上面 Kvantum 一直无法运行。kvantummanager 直接爆段错误,于是我便改环境变量强行 QT_STYLE_OVERRIDE=kvantum,结果,整个桌面直接爆了 …

编译一个带调试符号的 Kvantum 和 Qt base(五个小时啊 …),并用 gdb 调试,发现程序是在对一个未初始化的 QVariant 进行 toBool() 操作时爆掉的。

并且,这似乎不是 Kvantum 代码的问题,而是更底层的问题。

因为,我在这行代码前面加上一个 qDebug() << v <<;,就莫名其妙地可以跑通了 …

根据 archlinuxcn 群友指出,同一段代码在不同平台上编译出来的行为不一致,这肯定是一个未定义行为(Undefined behavior)。于是在群友的指导下,我分别打开 UBSanAsan 又编译了两次 Kvantum(两个小时过去了…),结果莫名其妙的是 —— 软件就这么水灵灵地跑起来了。头疼 …

后来 Kvantum 作者在 GitHub 讨论区指出,这很可能是编译器的锅。于是,我换用 clang 进行编译 …

跑起来了!

至于为什么会出现这个问题,是因为 C / C++ 并没有官方的编译器实现,只是发布了一份语言标准。在语言标准之外的某些行为上,各个编译器的实现都不一致,甚至也可能会出现我遇到的这种,在 x86_64 上编译出来是一种样子,在 arm64 上编译出来就是另外一种样子的情况。

所以,该启动 Ru …. (被打跑