Still haven't seen a great article describing the rules of pointer-to-member, but it seems like they aren't implicitly castable to long, so I would have to assume the lines
std::printf( "%ld\n", points_to_member_at_offset_0 ) ;
std::printf( "%ld\n", does_not_point ) ;
are going to give misleading results. If the first gives 0 though, I would expect the next to give -1 (as BlackSheep said), but it seems this would be entirely compiler dependent. It could theoretically be implemented as '5'; the compiler would know that while values '3', and '4', represent the 4th and 5th data members, values 6, 7, etc would represent the 6th, 7th, etc data members. Or for your 2nd question, 'null' could be '0' when viewed as an integer, with 1, 2, etc representing the 1st, 2nd, etc member variables.
The logic in
seems like it will work as expected regardless of the compiler. Whatever the conversion of
results in during the execution of
, the result will be the same when evaluating the line
if( pm != nullptr )
(which I believe could be simply written as
if( pm )
, given that conversion to bool does seem to be defined, and evaluates as 'true' even if the integral value is '0'). Likewise, regardless of the internal implementation of pointer-to-member,
a.*pm += v ;
seems like it would work in any case, as this is the proper syntax for this type of construct.