----- Hendrik Schober wrote: ----
AFAIK exceptions must have public cop
ctors, otherwise the program is ill
formed. I'd think that the compile
should issue an error, but I am afrai
this is a QoI issue and not required
I don't really buy this, and I still think it's
compiler bug. I don't have access to the Standard
but here's some of my reasonings
1. The public, protected, and private keywords ar
clearly intended to control compile-time behavior
with as few changes to the resulting code as possible
(There is the caveat that a struct with mixed acces
classes for its data shouldn't be expected to look the sam
in C). If making a function protected is going to break somethin
purely C++, it should break at compile-time, not at run-time
2. The function in question would never be calle
(using any working compiler or if we changed i
to public). I could have just as well made it privat
and left it undefined. An exception object shoul
have a public copy constructor since the thro
statement is always required to make a copy (unles
the return value optimization applies?), but the exceptio
object here is of class B, not A, and B's cop
constructor is public
3. The compiler gets opportunities to complain i
situations where the copy constructor of A would b
called by the exception-handling mechanisms. If w
have
B b
A& a=b
throw a
then the throw statement is required to make an
object, slicing b, and throw it. This probably ough
to respect the accessibility of A's copy constructo
from the context of the throw. And if we hav
catch (A a
by value instead of by reference, then a copy of th
exception object must be made to initialize a i
the catch block, whether the exception object itsel
was really an A or a B. So this probably ought t
respect accessibility from the context of the catch
And to repeat myself again, all this can be don
by the compiler rather than the runtime
4. My inspection of the data internal exception-relate
functions are passing around seems to indicat
that at the throw statement, the compiler creates
symbol it mangles suggesting "throw info for B
containing an array of type_info pointers with
symbol suggesting "catchable types for B". And whe
the copy constructor for A isn't accessible, typeid(A
gets omitted from that array. Though it's true tha
a global function can't catch A by value, there hardl
seems to be any reason to leave it out. At th
throw statement, the compiler has no clue who migh
be catching it---maybe by reference, or mayb
by value but in a member of A or B or a friend function
Plus, unless the compiler can generate multipl
"catchable types for B" things, it will behave exactl
the same even if both the throw and catch are i
members of A. In my original program where
discovered this, the equivalent of A inherite
std::exception, and I was throwing B and attemptin
to catch std::exception&, both of which had publi
copy constructors, but the accessibility of A stoppe
the compiler from searching up the class inheritanc
and the exception refused to catch as std::exception&
So does Microsoft need to change th
mechanism entirely or add flags to track whethe
the object may be caught by value? No, the simples
fix is to always consider base classes as 'catchable
and just check accessibility at the throw statemen
and at the catch statement if by value