title: Polymorphically catching an exception in a -fno-rtti shared library on Mac OS X
body: <p>I'm building a shared library with <code>f-no-rtti</code>. Internally, this library throws <code>std:invalid_argument</code> and catches <code>std::exception</code>, but the <code>catch</code> clause is never entered.</p>
  
  <p>The following code reproduces the problem (g++ 4.2, Mac OS X 10.6):</p>
  
  <pre><code>// library.cpp: exports f(), compiled with -fno-rtti
  #include &lt;stdexcept&gt;
  #include &lt;iostream&gt;
  extern "C" {
      void f() {
          try {
              throw std::invalid_argument("std::exception handler");
          } catch( std::exception&amp; e) {
              std::cout &lt;&lt; e.what() &lt;&lt; "\n";
          } catch(...) {
              std::cout &lt;&lt; "... handler\n";
          }
      }
  }
  </code></pre>
  
  <hr>
  
  <pre><code>// main.cpp: the main executable, dynamically loads the library
  #include &lt;dlfcn.h&gt;
  typedef void(*fPtr)();
  
  int main() {
      void* handle = dlopen( "./libexception_problem.dylib", RTLD_LAZY );
      fPtr p_f = reinterpret_cast&lt;fPtr&gt;( dlsym( handle, "f" ) );
      p_f();
  }
  </code></pre>
  
  <hr>
  
  <p>Output:</p>
  
  <pre><code>MacBook-Pro:teste pfranco$ # works fine with rtti
  MacBook-Pro:teste pfranco$ g++ -c library.cpp &amp;&amp; g++ -shared -o libexception_problem.dylib library.o &amp;&amp; g++ main.cpp -o main &amp;&amp; ./main
  std::exception handler
  MacBook-Pro:teste pfranco$ # breaks with -fno-rtti
  MacBook-Pro:teste pfranco$ g++ -c -fno-rtti library.cpp &amp;&amp; g++ -shared -o libexception_problem.dylib library.o &amp;&amp; g++ -fno-rtti main.cpp -o main &amp;&amp; ./main
  ... handler
  MacBook-Pro:teste pfranco$ #-no_dead_strip_inits_and_terms doesn't change anything
  MacBook-Pro:teste pfranco$ g++ -c -no_dead_strip_inits_and_terms -fno-rtti library.cpp &amp;&amp; g++ -no_dead_strip_inits_and_terms -shared -o libexception_problem.dylib library.o &amp;&amp; g++ -fno-rtti -no_dead_strip_inits_and_terms main.cpp -o main &amp;&amp; ./main
  ... handler
  MacBook-Pro:teste pfranco$ # linking against the shared library works, but this isn't always an option
  MacBook-Pro:teste pfranco$ g++ -c -fno-rtti library.cpp &amp;&amp; g++ -shared -o libexception_problem.dylib library.o &amp;&amp; g++ -fno-rtti main.cpp -o main -L. -lexception_problem &amp;&amp; ./main
  std::exception handler
  </code></pre>
  
  <hr>
  
  <p>This only happens if the code that throws is in a <strong>shared library</strong>, and only if the caught type is a <strong>base class</strong> of the actual exception -  <code>catch(std::invalid_argument&amp;)</code> works fine, <code>std::logic_error&amp;</code> doesn't.</p>
  
  <p>Interestingly, <strong>this doesn't happen on Linux</strong>, even when running the exact same commands.</p>
  
  <p><strong>Questions:</strong></p>
  
  <ol>
  <li>Why does this happen? Is this a bug, undefined behavior or by design?</li>
  <li>How could I make it work, short of linking against the library?</li>
  </ol>
  
  <p>Thanks a lot.</p>