This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


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

Re: exception specifications



> 15.4/2 says [all decls of a function] "shall have an 
> exception-specifier with the same set of type-ids." This implies that
> exception specifiers are sets.

Total agreement here.

> However, 15.4/6 says "an exception specification can include the
> same type more than once, and can include classes that are related
> by inheritance, even though doing so is redundant." So exceptions
> specification are not sets in the mathematical sense, but some kind
> of fuzzy set with semantics we must infer from the standard.

Well, they are sets. Sets can have different external representations,
repeating elements still doesn't change the set, in the mathematil sense:

S = { a, b, c}
S1 = S \/ {a}

S1 == S!

> 1) Are `throw(T)' and `throw(T, T)' the same?

Yes. It looks like this is the reason for allowing duplicates.

> Consider templatized exception> specifiers, ie `template<class T>
> void fn()throw(int, T);' The specialization `template<> void
> fn<int>()throw(int)' would be acceptable, which looks inconsistent.

No. Since we've decided that the throw-spec is not a lexical thing,
but semantical, it is very clear that {int, int} == {int}. Of course,
if people are not aware of this property, they write throw(int,int),
which is just as fine.

> 2) Are `throw(T)' and `throw(T, U)' the same, if U is singly derived
> from T? U is clearly redundant in the latter specification, but does
> that cause it to match the former?

No. U != T, so {T,U} != {U}. Of course, as an optimization, U could be
removed from the list of generated exceptions when generating
assembler code.

> 3) Ditto for T *, U * and for T &, U &.

Ditto.

> 4) (2) and (3) are really asking if 15.4/6 actually means `according
> to the matching semantics of catch clauses'. Then `T cv* cv' and `U
> cv *cv' all come into the picture.

They say mentioning subclasses is redundant, they don't lift the
restriction in 15.4/2, which asks for identical sets. When they say
'redundant', they mean with regard to 15.4/7: The base class already
allows the derived class.

> 5) If you believe we're doing catch clause-like matching, then presumably we
> should be ignoring the toplevel cv qualifiers of type-ids in the exception
> specifier.

We do not. 15.4/7 quite explicitly says what we do.

> 6) If throw(int) and throw(const int) are different throw specifiers,
> then 15.4/3 becomes strange. That says a virtual function overrider
> "shall only allow exceptions that are allowed by the exception
> specification of the base class virtual function". This is looser
> than (2). I.e, an overriding function `void U::fn() throw(int)'
> allows the same exceptions as a base function `void T::fn()
> throw(const int)', even though U::fn's exception specifier is not a
> subset of T::fn's.

No, it doesn't. If the base method allows (int), the derived method
can only *allow* (int) or (), but not (const int).

IMHO, anyway.

Regards,
Martin


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