c++visual-c++language-lawyercompiler-bug

Msvc compiles &(Class::mem) but gcc does not


I have recently learnt about pointer to member syntax and then wrote the program shown below that msvc compiles but gcc and clang rejects.

#include <iostream>
#include <type_traits> 
#include <concepts>
struct C
{
    int foo()
    {
    return 5;
    }
};
int main()
{ 
      int (C::*ptr)() = &(C::foo);   //msvc compiles but not gcc and clang  
}  

I want to know which one is correct. Live demo


Solution

  • This is P2904 which proposes that the program be well-formed.

    Note again that as per the current wording the program is ill-formed but the above paper proposes to make it well-formed by removing the exception in the normal precedence rules. Here is the relevant change in the wording as proposed by the paper:

    Change in wording

    Change [expr.unary.op#4] to as shown below:

    A pointer to member is only formed when an explicit & is used and its operand is a qualified-id not enclosed in parentheses.

    [Note 4: 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. The expression qualified-id does not form an expression of type pointer to member, be- cause there is no implicit conversion from a qualified-id for a non-static member function to the type “pointer to member function” as there is from an lvalue of function type to the type “pointer to function” ([conv.func]). Nor Neither is &unqualified-id a pointer to member, even within the scope of the unqualified-id’s class. — end note]