Consider the following code, where T
is a member pointer:
#include <cassert>
struct Foo { double v = 0; };
int main()
{
using T = double Foo::*;
T p1 = nullptr;
T p2 = T();
T p3{};
T * pp4 = new T();
T * pp5 = new T{};
assert(p1 == p2);
assert(p1 == p3);
assert(p1 == *pp4); // Fails on MSVC
assert(p1 == *pp5); // Fails on MSVC
delete pp4;
delete pp5;
}
clang and gcc compile and run this without problems (live on godbolt). However, MSVC (e.g. in version 19.35, but also others) does not: It compiles, but the asserts for pp4
and pp5
fail. If I understand the cppreference for value initialization correctly, pp4
and pp5
should be zero initialized, where in turn I would expect the resulting value to compare equal to nullptr
. Printing the values to cout
shows that all values are 0, except for pp4
and pp5
which are 1. Is this a MSVC bug, or is my understanding of member pointers and reading the cppreference wrong?
Background: Of course, having dynamically allocated member pointers is rather uncommon. I stumbled upon this while testing whether my tiny::optional
can cope with member pointers (optional<double Foo::*>
). Internally, the library uses placement new to construct the value, which shows the same issue.