I am reading code from here:
template<typename T> T Math::AngRound(T x) {
static const T z = 1/T(16);
if (x == 0) return 0;
GEOGRAPHICLIB_VOLATILE T y = abs(x);
// The compiler mustn't "simplify" z - (z - y) to y
y = y < z ? z - (z - y) : y;
return x < 0 ? -y : y;
}
where T
is double
and GEOGRAPHICLIB_VOLATILE
is volatile
.
And I wonder, are compilers allowed to "simplify" z - (z - y)
to y
, and is
that prevented by volatile
or not?
If it is relevant, I am interested in the C++17 standard.
Checking the assembly for clang showed that without volatile
-O3
doesn't cause the simplification of z - (z - y)
to y
.
On the other hand, icc simplifies the code in both cases: https://godbolt.org/z/rz7erdhev . If volatile is used, it adds an extra read, but not any real calculations.