这是一个计算整数除数的短程序.该程序确实正常工作.但问题是,在Clang C编译器(版本3.3,主干180686)的当前主干的-O3优化标志下,程序的行为发生变化,结果不再正确.
码
这是代码:
#include <iostream> constexpr unsigned long divisors(unsigned long n,unsigned long c) { // This is supposed to sum 1 anytime a divisor shows up // in the recursion return !c ? 0 : !(n % c) + divisors(n,c - 1); } int main() { // Here I print the number of divisors of 9 numbers! (from 1 to 9) for (unsigned long i = 1; i < 10; ++i) std::cout << i << " has " << divisors(i,i) << " divisors" << std::endl; }
正确的行为
这是使用的编译命令,以及程序在正常情况下显示的正确和预期输出:
clang++ -O2 -std=c++11 -stdlib=libc++ -lcxxrt -ldl sample.cpp -o sample ./sample 1 has 1 divisors 2 has 2 divisors 3 has 2 divisors 4 has 3 divisors 5 has 2 divisors 6 has 4 divisors 7 has 2 divisors 8 has 4 divisors 9 has 3 divisors
行为不正确
这是用于生成提供错误输出的二进制文件的命令行.请注意,唯一的更改是优化标志(-O2到-O3.)
clang++ -O3 -std=c++11 -stdlib=libc++ -lcxxrt -ldl sample.cpp -o sample ./sample 1 has 1 divisors 2 has 2 divisors 3 has 2 divisors 4 has 1 divisors 5 has 2 divisors 6 has 3 divisors 7 has 2 divisors 8 has 2 divisors 9 has 2 divisors
编辑
我已经更新到了行李箱,铿锵声版本3.4(行李箱183073).这种行为不再重现,应该已经以某种方式修复了.谁知道它是什么问题,如果有一个实际验证和修复,请随时提供答案.如果没有验证,则可能发生回归.
解决方法
看起来你被
this bug in llvm咬了.你可以通过禁用循环矢量化器来解决它,或者(正如你已经发现的那样),通过更新到比r181286更新的版本的llvm构建来解决它.
如果您查看差异,您将看到已添加测试用例作为修复的一部分.这应该可以防止这个问题在未来再次出现.
原文地址:https://www.jb51.cc/c/118915.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。