Consider the following snippet:
int main() {
struct Local {
virtual void foo() = 0;
};
void (Local::* ptr)() = &Local::foo;
}
When compiling with C++20, GCC 13.3.0 and Clang 18.1.3 both compile this code, but MSVC 19.39 thru 19.43 generate the following compiler error:
<source>(3): error C3640: 'main::Local::[thunk]: __cdecl `int __cdecl main(void)'::`2'::Local::`vcall'{0,{flat}}' }'': a referenced or virtual member function of a local class must be defined
I could not find anything in the C++20 standard to prove either compiler right. Is the code snippet well-formed?
Example on Compiler Explorer
I do not see anything in C++20 standard that makes the code in question ill-formed.
Microsoft admitted that it is a bug in the implementation of MSVC: https://developercommunity.visualstudio.com/t/Wrong-error-C3640-in-getting-a-pointer-o/10992438
And it is not hard to make the above program compile with MSVC by making member-function pointer not directly in the function containing the local class, but in some other function getFooPtr():
template<class T>
auto getFooPtr() {
return &T::foo;
}
int main() {
struct Local {
virtual void foo() = 0;
};
void (Local::* ptr)() = getFooPtr<Local>();
return ptr != nullptr;
}
Now the program is accepted in MSVC, as well as in GCC, Clang and EDG. Online demo: https://gcc.godbolt.org/z/cvPrn41b6
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