C++ 需要有关BOOST_FOREACH/编译器错误的帮助吗
我知道boost或编译器应该是最后一个罪魁祸首,但我在这里看不到其他解释。 我使用的是MSVC2008SP1和Boost1.43 在下面的代码段中,执行从不离开第三个BOOST\u FOREACH循环C++ 需要有关BOOST_FOREACH/编译器错误的帮助吗,c++,visual-c++,boost,boost-foreach,C++,Visual C++,Boost,Boost Foreach,我知道boost或编译器应该是最后一个罪魁祸首,但我在这里看不到其他解释。 我使用的是MSVC2008SP1和Boost1.43 在下面的代码段中,执行从不离开第三个BOOST\u FOREACH循环 typedef Graph<unsigned, unsigned>::VertexIterator Iter; Graph<unsigned, unsigned> g; g.createVertex(0x66); // works fine Iter it = g.ge
typedef Graph<unsigned, unsigned>::VertexIterator Iter;
Graph<unsigned, unsigned> g;
g.createVertex(0x66);
// works fine
Iter it = g.getVertices().first, end = g.getVertices().second;
for(; it != end; ++it)
;
// fine
std::pair<Iter, Iter> p = g.getVertices();
BOOST_FOREACH(unsigned handle, p)
;
// fine
unsigned vertex_count = 0;
BOOST_FOREACH(unsigned handle, g.getVertices())
vertex_count++;
// oops, infinite loop
vertex_count = 0;
BOOST_FOREACH(unsigned handle, g.getVertices())
vertex_count++;
vertex_count = 0;
BOOST_FOREACH(unsigned handle, g.getVertices())
vertex_count++;
// ... last block repeated 6 times
typedef图形::VertexIterator Iter;
图g;
g、 createVertex(0x66);
//很好
Iter it=g.getVertices().第一,end=g.getVertices().第二;
for(;it!=end;++it)
;
//好的
std::pair p=g.getVertices();
BOOST_FOREACH(无符号句柄,p)
;
//好的
无符号顶点计数=0;
BOOST_FOREACH(无符号句柄,g.getVertices())
顶点计数++;
//哦,无限循环
顶点计数=0;
BOOST_FOREACH(无符号句柄,g.getVertices())
顶点计数++;
顶点计数=0;
BOOST_FOREACH(无符号句柄,g.getVertices())
顶点计数++;
// ... 最后一个区块重复6次
迭代器代码:
class Iterator
: public boost::iterator_facade<Iterator, unsigned const,
boost::bidirectional_traversal_tag>
{
public:
Iterator()
: list(NULL), handle(INVALID_ELEMENT_HANDLE)
{}
explicit Iterator(const VectorElementsList &list, unsigned handle = INVALID_ELEMENT_HANDLE)
: list(&list), handle(handle)
{}
friend std::ostream&
operator<<(std::ostream &s, const Iterator &it)
{
s << "[list: " << it.list <<", handle: " << it.handle << "]";
return s;
}
private:
friend class boost::iterator_core_access;
void increment()
{
handle = list->getNext(handle);
}
void decrement()
{
handle = list->getPrev(handle);
}
unsigned const& dereference() const
{
return handle;
}
bool equal(Iterator const& other) const
{
return handle == other.handle && list == other.list;
}
const VectorElementsList<T> *list;
unsigned handle;
};
类迭代器
:public boost::迭代器
{
公众:
迭代器()
:列表(NULL)、句柄(无效的\u元素\u句柄)
{}
显式迭代器(const VectorElementsList&list,无符号句柄=无效的元素句柄)
:列表(&列表),句柄(句柄)
{}
friend std::ostream&
对于模板函数中的默认值,运算符看起来是这样的
2009年8月有一个非常类似的bug(在下一个版本中被M$修复)……它在很多方面都是一致的:它是VC++特有的,在GCC中工作,导致使用默认模板参数时出现间歇性故障(但从来没有编译时问题),问题只在第二次实例化时出现
也就是说,我无法解释编译器的输出,或者神奇的10个循环…:-)
VC++甚至有一篇关于的老文章。最近出现了非常类似的bug,而且你的bug和格林的bug的颜色看起来是多么一致,这可能是VC++而不是Boost
我的猜测?它被这些签名扼杀了:
const T&data=T()
在graph\u elements\u集合中。h.MSFT建议将其更改为const T data=T()
。要验证它是否与此编译器错误相关,请尝试一下,或者MSFT发布的解决方法……尝试添加/Oy-compiler标志(配置属性->C/C++->优化->禁用“忽略帧指针”)
我使用MSVC 2010解决了同样的问题,解决了这个问题!< /P>是否有可能提供一个可编译的测试用例?你是否尝试过将两个循环的汇编代码与相同的C++代码进行比较?这个循环必须重复10次的事实暗示这可能是一个优化相关的编译器Bug。THE013E1392?跳转到013E1380?这个循环的开始是差不多3年了……你收到微软的反馈或者是关于这个的提法吗?因为Visual C++ 2010现在已经可用了,你试过用新的编译器重复这个问题来看看问题是否消失了?如果是的话,你可以确信它是一个错误。为什么你会做
const t data=t()
而不仅仅是const t
@DeadMG:对不起,我不明白,你能详细说明一下吗?你已经默认构造了一个t,这样..你就可以用它来复制构造一个t?为什么不直接构造一个t呢?@Kate不完全是因为编译器中的其他更改可能会影响重新产生问题所需的循环数或其他一些细节。this bug对堆栈布局和空间辐射非常敏感@DeadMG with fn(const t data=t()),您可以调用fn而不使用参数@robert谢谢您的建议,但这似乎不是我的bug。我在这里制作了更简单的测试用例版本(根本没有default参数):
vertex_count = 0;
BOOST_FOREACH(unsigned handle, g.getVertices())
// initialization
013E1369 mov edi,dword ptr [___defaultmatherr+8 (13E5034h)] // end iterator handle: 0xFFFFFFFF
013E136F mov ebp,dword ptr [esp+0ACh] // begin iterator handle: 0x0
013E1376 lea esi,[esp+0A8h] // begin iterator list pointer
013E137D mov ebx,esi
013E137F nop
// forever loop begin
013E1380 cmp ebp,edi
013E1382 jne main+238h (13E1388h)
013E1384 cmp ebx,esi
013E1386 je main+244h (13E1394h)
013E1388 lea eax,[esp+18h]
013E138C push eax
// here iterator is incremented in ram
013E138D call boost::iterator_facade<detail::VectorElementsList<Graph<unsigned int,unsigned int>::VertexWrapper>::Iterator,unsigned int const ,boost::bidirectional_traversal_tag,unsigned int const &,int>::operator++ (13E18E0h)
013E1392 jmp main+230h (13E1380h)
vertex_count++;
// forever loop end