stl::set
Working with Mark’s dnl code, we came across an interesting issue. Mark had used the stl::set class for some of his code and whilst it compiled fine under Visual Studio, it failed to compile under gcc/g++. With the error:
dnlCommon/Logger.cpp: In member function 'void dnlCommon::Logger::setMask(std::ostream&, std::bitset<5ul>)': dnlCommon/Logger.cpp:64: error: invalid initialization of reference of type 'dnlCommon::Logger::LoggerPair&' from expression of type 'const dnlCommon::Logger::LoggerPair' /usr/local/lib/gcc-4.0.4/include/c++/bits/stl_algo.h: In function '_OutputIterator std::remove_copy(_InputIterator, _InputIterator, _OutputIterator, const _Tp&) [with _InputIterator = std::_Rb_tree_const_iterator<dnlCommon::Logger::LoggerPair>, _OutputIterator = std::_Rb_tree_const_iterator<dnlCommon::Logger::LoggerPair>, _Tp = dnlCommon::Logger::LoggerPair]': /usr/local/lib/gcc-4.0.4/include/c++/bits/stl_algo.h:1112: instantiated from '_ForwardIterator std::remove(_ForwardIterator, _ForwardIterator, const _Tp&) [with _ForwardIterator = std::_Rb_tree_const_iterator<dnlCommon::Logger::LoggerPair>, _Tp = dnlCommon::Logger::LoggerPair]' dnlCommon/Logger.cpp:54: instantiated from here /usr/local/lib/gcc-4.0.4/include/c++/bits/stl_algo.h:1037: error: passing 'const dnlCommon::Logger::LoggerPair' as 'this' argument of 'dnlCommon::Logger::LoggerPair& dnlCommon::Logger::LoggerPair::operator=(const dnlCommon::Logger::LoggerPair&)' discards qualifiers
It turned out that the issue occurred with the assignment operator (operator = ) on the stl::set
class. Tracing the problem we found that set<TYPE>::iterator
is const
rather than non cost. Hence calling stl functions that made use of the iterators but also the assignment operator would fail.
Looking further into the problem I found:
// _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 103. set::iterator is required to be modifiable, // but this allows modification of keys. typedef typename _Rep_type::const_iterator iterator; typedef typename _Rep_type::const_iterator const_iterator;
Hmm, that’s strange. A bit of googling revieled the problem to be an issue with the stl standard. Fixes to gcc/g++ are listed at http://gcc.gnu.org/onlinedocs/libstdc++/ext/howto.html in particular error 103 is listed at http://gcc.gnu.org/onlinedocs/libstdc++/ext/lwg-defects.html#103
So it looks like the bug was ratified by the C++ committee in 1998 and it still isn’t fixed in Visual Studio 2005 (VC++ 8.0) !
Leigh McCulloch said,
If I’m using a compiler that uses an old version that has this bug in it, is there anything I can do in my own code to get around it?
Leigh
Benjamin Close said,
Hi Leigh,
As far as I can tell, if your using VC things work as intended using the operator which should be const. However if you intend to port your code to later versions of VC++ or gcc you’ll need to fix the code – there’s no work around. The correct fix is not to use the operator = in this case. Instead use an operator in the class intended to set the values.
Leigh McCulloch said,
Mmm. I’m not sure I can do what I’m trying to do.
I’m using a remove_if to remove items in the set that meet certain requirements. But the remove_if is actually doing the operator=. I think I’ll just convert the code to use a vector instead, or I’ll do the remove_if manually with a loop.
Let me know if you have any other suggestions.
Leigh
Add A Comment