In the following program, struct A has both copy-constructor A(const A&) and a constructor from lvalue-reference A(A&). Then an object of A is thrown and then caught as const A:
#include <iostream>
struct A {
A() {}
A(A&) { std::cout << "A(A&) "; }
A(const A&) { std::cout << "A(const A&) "; }
};
int main() {
try {
throw A{};
}
catch ( const A ) {
}
}
All compilers accept the program.
As far as I understand exception objects are never cv-qualified, and handler variables are initialized from an lvalue that refers to them. So one could expect that A(A&) constructor be preferred in catch. And indeed Clang does so.
But GCC prefers copy constructor printing A(const A&). Demo: https://gcc.godbolt.org/z/1an5M7rWh
Even more weird thing happens in Visual Studio 2019 16.11.7, which prints nothing during program execution.
Which compiler is right here?