今天在 leetcode 上遇到一个 题目, 发现同样的逻辑 rust 输出错误答案。
最后把代码放到本地跑,发现 cargo run
得到正确结果,然而 cargo build --release
总是得到错误结果。
测试了一下 playground, 选 release 也是错误结果。
看起来是被过度优化了。
fn max_turbulence_size(arr: Vec<i32>) -> i32 {
let mut prev = 0;
let mut cnt = 0;
let mut ret = 0;
for w in arr.windows(2) {
let d = w[1] - w[0];
if d == 0 {
cnt = 0;
} else if d > 0 {
if prev < 0 {
cnt += 1;
} else {
cnt = 1;
}
} else {
if prev > 0 {
cnt += 1;
} else {
cnt = 1;
}
}
// Uncomment the follow line will give the right answer
// println!("{} {}", d, prev);
ret = ret.max(cnt);
// The follow line seems optimized out if we don't access `prev`, `d` simultaneously.
prev = d;
}
ret + 1
}
fn main() {
let v = vec![9,4,2,10,7,8,8,1,9];
let ans = max_turbulence_size(v);
// The right answer is 5. But when build with release, the output is 2
println!("{}", ans);
}
1
共 10 条评论, 1 页
评论区
写评论目前nightly已经可以正确编译
看了issue,只是惊叹LLVM竟然会有这种问题。逻辑一点也不特殊,很常见的代码片段啊。。。 会祸害很多生产代码。如果它们木有单侧,又处于关键的地方。就坑大了。
--
👇
Neutron3529: 这很科学
因为这是LLVM的问题
跟rust没关系。
--
👇
SkyWalker: 这不科学。。。
https://github.com/rust-lang/rust/issues/98568
我看 Rust 把你 issue 设置成 critical 优先级了,说明官方高度重视这个问题会尽快修复。哈哈也算刷题居然也能给编译器作贡献
这很科学
因为这是LLVM的问题
跟rust没关系。
--
👇
SkyWalker: 这不科学。。。
这不科学。。。
涨见识了。
这个demo把LLVM炸了
可怕……
有大佬给了个简化版本,https://godbolt.org/z/j538GxzT1
看起来整个循环都被优化掉了。
--
👇
soft5: 一个5,一个2,怪怪的,好像这句
prev = d;
没起到作用, prev 永远是0已经提了,好像 1.56 之后的都有问题
--
👇
songzhi: 看起来确实是一个bug,有空可以给Rust编译器提个issue,还是挺严重的。
一个5,一个2,怪怪的,好像这句
prev = d;
没起到作用, prev 永远是0看起来确实是一个bug,有空可以给Rust编译器提个issue,还是挺严重的。