title: Catching exceptions by `const` value in C++. Compilers diverge
body: <p>In the following program, struct <code>A</code> has both copy-constructor <code>A(const A&amp;)</code> and a constructor from lvalue-reference <code>A(A&amp;)</code>. Then an object of <code>A</code> is thrown and then caught as <code>const A</code>:</p>
  <pre><code>#include &lt;iostream&gt;
  
  struct A {
      A() {}
      A(A&amp;) { std::cout &lt;&lt; &quot;A(A&amp;) &quot;; }
      A(const A&amp;) { std::cout &lt;&lt; &quot;A(const A&amp;) &quot;; }
  };
  
  int main() {
      try {
          throw A{};
      }
      catch ( const A ) {
      }
  }
  </code></pre>
  <p>All compilers accept the program.</p>
  <p>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 <code>A(A&amp;)</code> constructor be preferred in <code>catch</code>. And indeed Clang does so.</p>
  <p>But GCC prefers copy constructor printing <code>A(const A&amp;)</code>. Demo: <a href="https://gcc.godbolt.org/z/1an5M7rWh" rel="noreferrer">https://gcc.godbolt.org/z/1an5M7rWh</a></p>
  <p>Even more weird thing happens in Visual Studio 2019 16.11.7, which prints nothing during program execution.</p>
  <p>Which compiler is right here?</p>