This is the mail archive of the mailing list for the libstdc++ project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: throw specs on Standard destructors

On Tue, Dec 10, 2002 at 12:41:08PM -0600, Benjamin Kosnik wrote:
> >#include <string>
> >struct Base {  virtual ~Base() throw() {} };
> >struct Der : Base { std::string foo; };
> >int main() { Der d; }
> ...
> >The problem here is that the default destructor for
> >Der will have a throw spec which is the union of all
> >bases and members.  Since std::basic_string has no
> >throw spec, Der::~Der also will have none, which
> >violates Base's destructor's spec.
> >I would assume the same should be done for auto_ptr.
> Where would it stop? That part is unclear to me.
> I think patches of this type are acceptable. Interested?

While it might be relatively harmless to add throw specs here and 
there, there would be effects.  

First, in any function so declared that itself called a function 
which might throw something not listed, the compiler would have to 
generate code to catch them and call terminate().  

Second, if it later became necessary to allow such a function
to throw an exception not listed, any code that depended on its 
previous spec would be broken.

Third, any code that depends on tight throw specs in libstdc++
would not be portable to other implementations.

IMHO the declaration in Base above really is in error.  Changing 
our headers to conceal the error would not be doing anyone a favor.

Empty throw specs may be useful when applied to call-graph-leaf 
functions, and (transitively) functions that call only them.  
This is purely an implementation optimization trick, and depends 
on the compiler to cooperate by generating simpler code to call 
such functions.  It always makes sense to mark extern "C" function 
decls as "throw ()", for example.

We should accept throw spec patches only for cases where it is 
demonstrable that smaller or faster code results.  

The case of basic_string<>::~basic_string is smack on the borderline.
It's called just frequently enough to make the difference worthwhile,
and we can be certain we'll never need to change it because you can
only instantiate basic_string<> on a POD.  But it would not suffice 
just to add the spec; we would also need to make sure everything it 
calls is either wrapped in a try/catch block or is also so declared, 
and on down the line.  

Nathan Myers

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]