Issue with bounds checking a member std::array inside a const function

c++, c++11, mingw

Solution

This is part of array header

#ifdef __EXCEPTIONS
  constexpr const_reference
  at(size_type __n) const
  {
return __n < _Nm ? 
       _M_instance[__n] : throw out_of_range(__N("array::at"));
  }
#else
  const_reference
  at(size_type __n) const
  {
if (__n >= _Nm)
  std::__throw_out_of_range(__N("array::at"));
return _M_instance[__n];
  }
#endif

Undef __EXCEPTIONS in main file(or change `#ifdef` to `#ifndef` in array) leads to correct output. I don't know, this is right solution or not, but it works.

UPD: I change the code in my array's header to

#ifdef __EXCEPTIONS
  constexpr const_reference
  at(size_type __n) const
  {
return __n < _Nm ? 
       _M_instance[__n] : (throw out_of_range(__N("array::at"))),
                          _M_instance[__n];
   /*return __n < _Nm ? 
            _M_instance[__n] : throw out_of_range(__N("array::at"));*/
  }
#else
  const_reference
  at(size_type __n) const
  {
if (__n >= _Nm)
  std::__throw_out_of_range(__N("array::at"));
return _M_instance[__n];
  }
#endif

Now everything is working correctly

Problem

I'm getting strange behavior bounds checking a member std::array with mingw (gcc 4.7.0) with the following code ``` #include <iostream> #include <array> class testClass { std::array<int, 2> testArray; public: testClass(); void func() const; }; testClass::testClass() : testArray({{1, 2}}) { } void testClass::func() const { for (int i = 0; i < 2; ++i) std::cout << testArray.at(i) << '\n' << testArray[i] << '\n'; } int main() { testClass test; test.func(); } ``` Output is ``` 0 1 0 2 ``` The error seems to be related to optimization, as it only crops up when compiled with `-O`, I tried the individual flags enabled by `-O` but couldn't narrow it down any further. Making the function non-const also fixes the issue. Could this be a bug or am I missing something? *edit Narrowed it down, looks like a bug in the `const` version of `.at()` ``` #include <iostream> #include <array> int main() { std::array<int, 2> const testArray = {1, 2}; for (int i = 0; i < 2; ++i) std::cout << testArray.at(i) << '\n' << testArray[i] << '\n'; } ``` Same output as above compiled with `-std=c++11 -O` using mingw 4.7.0 on Windows Xp sp3 and Windows 7 sp1. *edit 2 Same output again ``` #include <iostream> #include <array> int main() { typedef std::array<int, 2> Tarray; Tarray test = {1, 2}; for (int i = 0; i < 2; ++i) std::cout << const_cast<Tarray const*>(&test)->at(i) << '\n' << test.at(i) << '\n'; } ```

Original source