我正在使用以下代码检查带有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';
}
在Windows Xp sp3和Windows 7 sp1上使用mingw 4.7.0与-std=c++11 -O
编译的输出相同。
*编辑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';
}
答案 0 :(得分: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
现在一切正常