Issue
so I wrote this code:
#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;
}
}
And without optimizations it works as expected, prints 11 values with last one being random value. But as soon I move to -O2 I get randomly long list of numbers finished with crash and segmentation fault. I checked this result on godbolt.org (https://godbolt.org/z/4MqjbPbxE) and it seems that it is not a problem in, for example, clang.
My question is, is this a bug in gcc? Why would optimizations remove/not check condition in for loop?
Solution
You are invoking undefined behavior by using out-of-range x[i]
.
Allocate one more to avoid out-of-range access.
In other words,
constexpr auto x = array<10, fibonacci>();
should be
constexpr auto x = array<11, fibonacci>();
Defining constant to avoid typo is better:
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;
}
}
Answered By - MikeCAT