Q1: There is special meaning to the syntax of &
followed by an unparenthesized qualified-id. It means to form a pointer-to-member. Furthermore, there is no other way to form a pointer-to-member. This is covered by C++17 [expr.unary.op]/4:
A pointer to member is only formed when an explicit &
is used and its operand is a qualified-id not enclosed in parentheses. [Note: That is, the expression &(qualified-id)
, where the qualified-id is enclosed in parentheses, does not form an expression of type “pointer to member”. Neither does qualified-id [...]
Q3: In both cases where you write printf("%p\n", &C::c);
, &C::c
is a pointer-to-member. The %p
format specifier is only for void *
so this causes undefined behaviour, and the program output is meaningless.
The code cout << &C::c;
outputs a pointer-to-member via operator<<(bool val)
, since there is implicit conversion from pointer-to-member to bool
(with result true
in all cases), see [conv.bool]/1.
For further discussion of how to print a pointer-to-member, see this answer.
Q2: The code &(C::c)
does not form a pointer-to-member as explained above.
Now, the code C::c
is in the grammatical category id-expression. (Which is qualified-id and unqualified-id). An id-expression has some restrictions on its use, [expr.prim.id]/1:
An id-expression that denotes a non-static data member or non-static member function of a class can only be used:
- as part of a class member access in which the object expression refers to the member’s class or a class derived from that class, or
- to form a pointer to member (7.6.2.1), or
- if that id-expression denotes a non-static data member and it appears in an unevaluated operand.
When we are inside the C::foo
function, the first of those bullet points applies. The code is the same as &c
but with unnecessary qualification. This has type int *
. You could output this with std::cout << &(C::c);
which would show a memory address, the address of this->c
.
When we are in the main
function , none of the three bullet points apply and therefore the &(C::c)
is ill-formed.