4

I wrote the following program that compiles with msvc but rejected by clang and gcc. It uses explicit object member function. Demo.

#include <iostream>

struct C{
   int f(this int);
};

decltype(C::f) func; //msvc accepts but clang and gcc rejects
  

int func(int j)
{
   std::cout << "called with: " << j << std::endl;
   return 5;
}

As you can see msvc accepts this program but gcc says:

<source>:7:13: error: invalid use of non-static member function 'int C::f(this int)'
    7 | decltype(C::f) func;
      |             ^
<source>:7:13: error: invalid use of non-static member function 'int C::f(this int)'
<source>:7:13: error: invalid use of non-static member function 'int C::f(this int)'
      |   
<source>: At global scope:
<source>:13:15: error: 'int func(int)' redeclared as different kind of entity
   13 | int func(int j)
      |               ^
<source>:7:16: note: previous declaration 'int func'
    7 | decltype(C::f) func;
      |                ^~~~

I want to know if this is well-formed or ill-formed etc as per the c++ standard.

4
  • MSVC has yet an incomplete support for C++23. Commented Jul 12, 2024 at 7:43
  • 1
    This seems well-formed by omission as [expr.prim.id.general] doesn't place the same restriction on use of explicit object member function as it does on implicit object member function. Commented Jul 12, 2024 at 7:43
  • 2
    @prapin That does not seem to be the case here. Commented Jul 12, 2024 at 7:49
  • 1
    This is a confirmed clang bug. MSVC is the only standard conformant compiler here. Commented Jul 13, 2024 at 5:16

1 Answer 1

0

I want to know if this is well-formed or ill-formed etc as per the c++ standard.

This is a confirmed clang bug and the program(decltype(C::f)) is well-formed. That is, msvc is the only standard conformant compiler here.

This can be seen from expr.prim.id.general that only puts a restriction on implicit object member function and non-static data member but not explicit object member function.

Basically, expr.prim.id.general doesn't place the same restriction on use of explicit object member function as it does on implicit object member function.

From expr.prim.id.general:

An id-expression that denotes a non-static data member or implicit object member function of a class can only be used:

  • as part of a class member access (after any implicit transformation (see above)) 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 ([expr.unary.op]), or
  • if that id-expression denotes a non-static data member and it appears in an unevaluated operand.

(emphasis mine)

Note the emphasis on implicit object member function and there is no restriction on explicit object member function. So the program is well-formed.

Sign up to request clarification or add additional context in comments.

1 Comment

Why the downvotes? There is nothing wrong with the answer. My answer is correct and this is a confirmed clang bug.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.