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)'
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With