I have the following code snippet that behaves as expected on gcc and clang. However, MSVC gives me an unexpected result.
Let's look at the problematic code first.
#include <iostream> // ----------------------------------------------- class Test // Dummy for MCVE { public: Test(); void Print(); private: int arr[5]; }; Test tst; // ----------------------------------------------- template<typename T> struct range // some stuff not needed by example removed { constexpr range(T n) : b(0), e(n) {} constexpr range(T b, T e) : b(b), e(e) {} struct iterator { T operator*() { return i; } iterator& operator++() { ++i; return *this; } bool operator!=(iterator other) { return i != other.i ; } T i; }; iterator begin() const { return{ b }; } iterator end() const { return{ e }; } private: T b,e; }; constexpr range<int> coord(5); // ----------------------------------------------- Test::Test() { for(auto i : coord) arr[i]=i; } void Test::Print() { for(auto i : coord) std::cout << arr[i] << std::endl; } // ----------------------------------------------- int main() { tst.Print(); }
Now, on both clang and gcc, this prints '0 1 2 3 4'
However on MSVC it prints "0 0 0 0 0"
The reason is that when the constructor of the global variable tst blank, the “coordination” has not yet been initialized (up to 0.5), but also not random, but rather (0,0).
It would be wise for me that the constexpr initialization happens before the correct initialization. Is MSVC consistent in this behavior?
I should notice that I am using MSVC version 14.0.22823.1 and that the expected result can be obtained by changing the order of declaration
source share