Below program has been reduced as far as possible to show the issue encountered with Visual Studio C++ compiler.
f
is some algorithm function taking on input predicate object P p
, which has user-defined copy constructor that remembers the pointer on the source object. In that constructor it is checked that source and copy objects are distinct indeed if (s == this) throw 0;
but in operator ()
the same check returns the opposite result:
struct P {
const P * s = nullptr;
constexpr P() {}
constexpr P(const P & p) : s(&p) {
if (s == this) throw 0; // never happens
}
constexpr bool operator()() const {
return s != this; // shall be always true?
}
};
constexpr bool f(P p) {
return p.s ? p() : f(p);
}
int main() {
static_assert( f(P{}) ); // fails in MSVC, where static_assert( f(P{}) == false );
}
Online demo: https://gcc.godbolt.org/z/nqYoshExj
How can one explain that the same check passes in an object’s constructor, but then fails in its method?