问题描述
所以我写了这段代码:
#include <iostream>
constexpr
int fibonacci (int n) {
int a = 0;
int b = 1;
for(auto i = 0; i < n; i++) {
b += a;
a = b - a;
}
return b;
}
template<int N,int (T)(int)>
struct array {
using type = decltype(T(0));
constexpr array() : arr() {
for (auto i = 0; i < N; ++i) {
arr[i] = T(i);
}
}
const type &operator[](int i) const { return arr[i]; }
private:
type arr[N];
};
int main() {
constexpr auto x = array<10,fibonacci>();
for (int i = 0; i < 11; i++) {
std::cout << i << " " << x[i] << std::endl;
}
}
如果没有优化,它会按预期工作,打印 11 个值,最后一个是随机值。但是一旦我移动到 -O2,我就会随机得到一长串以崩溃和分段错误完成的数字。 我在godbolt.org (https://godbolt.org/z/4MqjbPbxE) 上查看了这个结果,似乎在例如clang 中没有问题。
我的问题是,这是 gcc 中的错误吗?为什么优化会删除/不检查 for 循环中的条件?
解决方法
您正在使用超出范围的 x[i]
调用未定义的行为。
再分配一个以避免超出范围的访问。
换句话说,
constexpr auto x = array<10,fibonacci>();
应该
constexpr auto x = array<11,fibonacci>();
定义常量以避免拼写错误更好:
int main() {
constexpr int num = 11;
constexpr auto x = array<num,fibonacci>();
for (int i = 0; i < num; i++) {
std::cout << i << " " << x[i] << std::endl;
}
}
,
修复检查索引。
for (int i = 0; i ; i++) {