Suppose I have the following two files, main.cpp
:
#include <iostream>
class A {};
void foo();
int main(void)
{
try {
foo();
}
catch(const A& e) {
std::cout << "Caught an A." << std::endl;
}
return 0;
}
and foo.cpp
:
class A {};
class B : public A {};
void foo()
{
B b;
throw b;
}
Now, when I compile each of these files separately, link the resulting object files, and run the resulting executable, I get the expected result:
$ clang++ --std=c++14 -c main.cpp
$ clang++ --std=c++14 -c foo.cpp
$ clang++ --std=c++14 main.o foo.o
$ ./a.out
Caught an A.
And that boggles my mind! Class A
has no virtual methods. Therefore, it is not polymorphic and its instances should carry no type information at runtime. The main.o
object file is unaware of what is being thrown, since the actual throwing takes place inside foo()
, whose body is defined in a separate compilation unit. The foo.o
object file has more information, but is equally unaware of any catch statements and the expected types of caught exceptions.
In short: I do not see how the two source files compiled separately and then linked can produce the above input without having some runtime type information at disposal. Neither file compiled separately should have enough information to take the right catch block.