Question

Explicit this object parameter wonkiness

There was some code floating around on Reddit that defined a member-function with an explicit this object parameter defined as type int. This made me wonder how this member-function could possibly be invoked.

After doing some tests, all of the compilers (Clang, GCC, and MSVC) seem to produce different results. So, this raises the question; is the following code legal and in accordance with the C++23 standard?

struct w { constexpr bool f(this int) { return true; } };
static_assert((*&w::f)(1)); // clang ok, gcc ok, msvc nope
static_assert((*&w::f)(0)); // clang ok, gcc nope, msvc nope

Demo


GCC's error message:

<source>:3:23: error: non-constant condition for static assertion
    3 | static_assert((*&w::f)(0));
      |               ~~~~~~~~^~~
<source>:3:24: error: dereferencing a null pointer
    3 | static_assert((*&w::f)(0));
      |   

MSVC's error message:

<source>(2): error C2660: 'w::f': function does not take 1 arguments
<source>(1): note: see declaration of 'w::f'
<source>(2): note: while trying to match the argument list '(int)'
<source>(3): error C2660: 'w::f': function does not take 1 arguments
<source>(1): note: see declaration of 'w::f'
<source>(3): note: while trying to match the argument list '(int)'
 9  376  9
1 Jan 1970

Solution

 3

I also think Clang is the only compiler behaving correctly here.

this int in itself is fine. I do not see any restrictions on the type of the explicit object parameter.

&w::f is clearly defined to give a bool(*)(int) pointing to the member function.

(*&w::f)(1) and (*&w::f)(0) should then be normal calls that match the call arguments in order to the parameters of the function, so 1 or 0 will be the argument to the explicit object parameter. There won't be any problem with the call as 1 and 0 can be used as arguments for an int parameter.

So it looks to me like bugs in GCC and MSVC.

2024-07-11
user17732522