这是带有 minmax 和结构化绑定的 gcc 和 clang 优化器错误吗?
Is this gcc and clang optimizer bug with minmax and structured binding?
这个程序,用 -std=c++20
标志构建:
#include <iostream>
using namespace std;
int main() {
auto [n, m] = minmax(3, 4);
cout << n << " " << m << endl;
}
在未使用优化标志 -Ox
时产生预期结果 3 4
。使用优化标志,它输出 0 0
。我用 -O1
、-O2
和 -O3
标志的多个 gcc 版本进行了尝试。
Clang 13 工作正常,但 clang 10 和 11 输出 0 4198864
优化级别 -O2
或更高。 ICC 工作正常。这里发生了什么?
std::minmax
的重载采用两个参数 returns 一对对参数的引用。然而,参数的生命周期在完整表达式的末尾结束,因为它们是临时的。
因此输出行正在读取悬挂引用,导致您的程序具有未定义的行为。
相反,您可以使用 std::tie
接收 by-value:
#include <iostream>
#include <tuple>
#include <algorithm>
int main() {
int n, m;
std::tie(n,m) = std::minmax(3, 4);
std::cout << n << " " << m << std::endl;
}
或者您可以使用 std::minmax
的 std::initializer_list
重载,其中 returns 一对值:
#include <iostream>
#include <algorithm>
int main() {
auto [n, m] = std::minmax({3, 4});
std::cout << n << " " << m << std::endl;
}
这个程序,用 -std=c++20
标志构建:
#include <iostream>
using namespace std;
int main() {
auto [n, m] = minmax(3, 4);
cout << n << " " << m << endl;
}
在未使用优化标志 -Ox
时产生预期结果 3 4
。使用优化标志,它输出 0 0
。我用 -O1
、-O2
和 -O3
标志的多个 gcc 版本进行了尝试。
Clang 13 工作正常,但 clang 10 和 11 输出 0 4198864
优化级别 -O2
或更高。 ICC 工作正常。这里发生了什么?
std::minmax
的重载采用两个参数 returns 一对对参数的引用。然而,参数的生命周期在完整表达式的末尾结束,因为它们是临时的。
因此输出行正在读取悬挂引用,导致您的程序具有未定义的行为。
相反,您可以使用 std::tie
接收 by-value:
#include <iostream>
#include <tuple>
#include <algorithm>
int main() {
int n, m;
std::tie(n,m) = std::minmax(3, 4);
std::cout << n << " " << m << std::endl;
}
或者您可以使用 std::minmax
的 std::initializer_list
重载,其中 returns 一对值:
#include <iostream>
#include <algorithm>
int main() {
auto [n, m] = std::minmax({3, 4});
std::cout << n << " " << m << std::endl;
}