8

次のコードを使用して、mingw (gcc 4.7.0) でメンバー std::array をチェックすると、奇妙な動作境界が発生します。

#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();
}

出力は

0
1
0
2

このエラーは最適化に関連しているよう-Oです-O. 関数を非 const にすると、問題も修正されます。これはバグでしょうか、それとも何か不足していますか?

*編集

絞り込むと、のconstバージョンのバグのように見えます.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';       
}

-std=c++11 -OWindows Xp sp3 および Windows 7 sp1 で mingw 4.7.0を使用してコンパイルされた上記と同じ出力。

*編集2

再び同じ出力

#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';     
}
4

1 に答える 1

5

これは配列ヘッダーの一部です

#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 (または配列の変更)#ifdefにより#ifndef、正しい出力が得られます。これが正しい解決策かどうかはわかりませんが、うまくいきます。

UPD:配列のヘッダーのコードを次のように変更します

#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

現在、すべてが正しく機能しています

于 2012-08-27T06:02:45.140 に答える