Fix "warning: assuming signed overflow does not occur when assuming that (X + c) < X is always false [-Wstrict-overflow]"
This was a tricky one. It was highly non-obvious why the compiler even ran
into this issue. My best guess is as follows: The compiler was trying to
optimize the loop over the vertices in testStaticRefinementGeometry()
,
test-refinement.cc:122. To do this it needed to statically evaluate
vEnd(refinement)
, where refinement
is unsigned, but converted to int due to
the signature of vEnd()
. The constructed iterator stores it as unsigned
_level
, and it also stores the current position as unsigned _index
. So there
is a conversion from unsigned to int and back to unsigned.
Changing the parameter and return value of vEnd()
to unsigned turns out not to
be enough: vEnd
calls nVertices()
, which also takes and returns an int.
Changing that to unsigned too is still not enough, because nVertices
evaluates
the expression Power<dimension>::eval((1<<level)+1)
. While level
is now
unsigned, the literal 1
's are not, and the result of operator<<()
will have
the type of the (promoted) left operand (the "usual integral conversions" do
not happen for <<
). Thus we need to change the literals to 1u
.
To be clear: the warning happens because of conversion from unsigned to int and then back to unsigned, where the compiler is unable to fully track all possible values and cannot prove that everything is fine.
This patch fixes this by making the level parameter unsigned, and by making sure that any literals are suffixed by u.
Adresses #5 (closed).
Merge request reports
Activity
mentioned in issue #5 (closed)
125 125 { 126 126 return VertexIterator(nVertices(level),level); 127 127 } 128 128 129 129 template<int dimension, class CoordType> 130 int 130 unsigned 131 131 RefinementImp<dimension, CoordType>:: 132 nElements(int level) 132 nElements(unsigned level) 133 133 { 134 static_assert(dimension >= 0, 135 "Negative dimension given, what the heck is that supposed to mean?"); 134 136 // return (2^level)^dim 135 return 1<<(level*dimension); 137 return 1u<<(level*unsigned(dimension));