New user self-registration is disabled due to spam. Please email eigen-core-team @ lists.tuxfamily.org if you need an account.
Before reporting a bug, please make sure that your Eigen version is up-to-date!
Bug 1192 - SparseMatrix::InnerIterator is missing comparison operators
Summary: SparseMatrix::InnerIterator is missing comparison operators
Status: NEW
Alias: None
Product: Eigen
Classification: Unclassified
Component: Sparse (show other bugs)
Version: 3.2
Hardware: All All
: Normal Unknown
Assignee: Nobody
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-04-05 17:44 UTC by Matthew Woehlke
Modified: 2016-04-05 18:05 UTC (History)
2 users (show)



Attachments

Description Matthew Woehlke 2016-04-05 17:44:27 UTC
There are no comparison operators for SparseMatrix::InnerIterator, but there is a non-explicit (which maybe should be explicit!) conversion operator to bool. As a result, a naïve attempt to compare these iterators compiles, but is subtly broken because the result tests if both iterators are *valid*, not if both iterators are the *same*.

This caused a program crash in our application (MapGUI) due to use of such iterators (via [1]) in an emulated ranged-based for loop ([2]) which compares a 'current' and 'previous' iterator in order to implement a do-once loop (used to declare a local variable in the init block of the for loop).

[1] https://github.com/Kitware/vital/blob/master/vital/util/enumerate_matrix.h
[2] https://github.com/Kitware/vital/blob/master/vital/vital_foreach.h (see the not-C++11, not-boost implementation)

Please implement == and != operators for this iterator, as are expected to be defined for iterators.
Comment 1 Matthew Woehlke 2016-04-05 18:05:50 UTC
I can work around this issue because the loop comparison is calling the operator== of a wrapping iterator, and I can add a work-around to that implementation. In general, however, there is a nasty and subtle behavior with the current implementation:

  InnerIterator iter = ...; // precondition: iter is valid
  auto sentinel = iter;
  for (auto value = *iter; iter == sentinel; ++iter)
  { ... }

From casual examination, the above loop should execute exactly once. This is not the actual behavior. (This is a simplification of the logic that's causing us trouble.)

Note You need to log in before you can comment on or make changes to this bug.