Crash in MSVC Debug mode caused by disabling of iterator debugging in vector_sparse.hpp
- Dominant language
- C++
- Stars
- 122
- Forks
- 151
- PR merge metrics
- No merged PRs in 30d
Description
This was a tricky issue to find (from where I started)!
At the following line in code: https://github.com/boostorg/ublas/blob/cf72d035f4f54c1fca3fa8882007a338c03b594b/include/boost/numeric/ublas/vector_sparse.hpp#L34 the MSVC iterator debugging is temporarily switched off because it was causing issues when the sparse matrix was comparing iterators. The iterators are from different containers and the iterator debugging complains about this.
However this method of fixing causes real problems for the following reason.
_ITERATOR_DEBUG_LEVEL 2 results in a different definition of the std iterator classes (with extra members to enable debugging when it is temporarily disabled in this file we end up with two incompatible definitions and the potential (a reality in my case) for unexplained crashes in code very far from this library.
I have an alternative fix which uses the _Unwrapped() function (see https://devblogs.microsoft.com/cppblog/stl-features-and-fixes-in-vs-2017-15-8/) which allows access to an unchecked version of the iterators. I think this is the basis for a solution, but so far I have only fixed instances that were causing assertions in the unit tests (see below) and I don't know the code well enough to determine whether there are other cases (it looks like there could very well be). Also, I don't know coding guidelines well enough to know whether this should be refactored to avoid many #ifs in the code.
Review of this and a proper fix, very much appreciated :-)
Here is the basis of the suggested fix:
in `vector_sparse.hpp` remove the following preprocessor code:
```cpp
#ifdef BOOST_MSVC
#define _BACKUP_ITERATOR_DEBUG_LEVEL _ITERATOR_DEBUG_LEVEL
#undef _ITERATOR_DEBUG_LEVEL
#define _ITERATOR_DEBUG_LEVEL 0
#endif
```
... and at end of the file, remove:
```cpp
#ifdef BOOST_MSVC
#undef _ITERATOR_DEBUG_LEVEL
#define _ITERATOR_DEBUG_LEVEL _BACKUP_ITERATOR_DEBUG_LEVEL
#undef _BACKUP_ITERATOR_DEBUG_LEVEL
#endif
```
in matrix_sparse.hpp make the following change to operator == () functions, as required (lines 2118, 2305 & 2517 fix the unit tests) :
```cpp
#if defined BOOST_MSVC && defined _ITERATOR_DEBUG_LEVEL && _ITERATOR_DEBUG_LEVEL >= 2
return it_._Unwrapped() == it.it_._Unwrapped();
#else
return it_ == it.it_;
#endif
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.