Topic: Question on Excception specifications


Author: "Paul D. DeRocco" <pderocco@strip_these_words.ix.netcom.com>
Date: 1997/05/29
Raw View
Ravikant Iyer wrote:

> 15.4 [except.spec] para 1 prohibits from incomplete types in
> exception-specifications. I was wondering what could be the reason for this.
>
> This prevents me from writing code like this..
>
> class Exception1;
> class Exception2;
>
> struct foo
> {
>         void foo1() throw (Exception1);
>         void foo2() throw (Exception2);
> };
>
> This means that any one who uses the header in which foo is defined would
> have to drag along definitions for _all_ classes used in all the exception
> specifications in that one file.. If a particular module wants to use foo1
> to only call foo1 member function then that module has no use for the
> definition of Exception2.

One reason is that the compiler may wish to make deductions based on
inheritance relationships among exceptions:

 extern void foo() throw(X);

 void bar() throw(Y) { foo(); }

Is this legal? It is if X is derived from Y, but that involves knowing
the complete types.

--

Ciao,
Paul

(Please remove the "strip_these_words." prefix from the return
address, which has been altered to foil junk mail senders.)
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1997/05/29
Raw View
Paul D DeRocco writes:

> Ravikant Iyer wrote:
>> 15.4 [except.spec] para 1 prohibits from incomplete types in
>> exception-specifications. I was wondering what could be the reason for this.

> One reason is that the compiler may wish to make deductions based on
> inheritance relationships among exceptions:

>  extern void foo() throw(X);

>  void bar() throw(Y) { foo(); }

> Is this legal? It is if X is derived from Y, but that involves knowing
> the complete types.

Well, this is legal even if X is not derived from Y.  However, if it
is not, if foo throws X, instead of getting the stack unwound out of
bar, unexpected will be invoked.  I can't see any way a compiler would
need complete type information at compile-time---althogh the runtime
would certainly need complete RTTI.

A stronger reason for requiring complete types:

struct base { virtual void foo() throw(X); };
struct derived : public base { void foo() throw(Y); };

Is derived::foo acceptable?  It should only be considered valid if Y
is certainly unambiguously derived from X.  If Y is an incomplete
type, though, the compiler can't tell, and the decision would have to
be left for runtime.  If foo is going to propagate an exception, it
must ensure that such an exception is both an X and a Y.  Now imagine
a deep inheritance hierarchy with dozens of exception specifications
for each member function in each level!

Although implementing that check at run-time is possible (as far as I
can see), it is too costly if the complete types are not known at
compile time.


Another problem of allowing this check to be delayed to runtime is
that it may have unexpected interactions with the One Definition Rule.
Some functions are allowed to be given multiple definitions in
different translation units that compose a program, as long as these
definitions are exactly the same, as stated in [basic.def.odr].  If,
at the point of definition of such a function in one translation unit
X and Y are complete types, the check can be performed at
compile-time; in another, where X and Y are incomplete types, the
check is delayed to runtime.  Now you have two different versions of
the same function, just because in one of them a type was defined and
in another it was not.

This might lead to one of two requirements: any function that might be
given multiple definitions and has an exception specification must
have exactly the same set of exception types complete and incomplete
than in any other translation unit (and it would be quite hard to
require a diagnostic for that), or the decision must always be delayed
to runtime in such functions.

--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org
Universidade Estadual de Campinas, SP, Brasil
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Ravikant Iyer <bom@slip.net>
Date: 1997/05/29
Raw View
In article <338D32FB.6C6C@strip_these_words.ix.netcom.com>,
Paul D. DeRocco <pderocco@strip_these_words.ix.netcom.com> wrote:
[snip]
>One reason is that the compiler may wish to make deductions based on
>inheritance relationships among exceptions:
>
> extern void foo() throw(X);
>
> void bar() throw(Y) { foo(); }
>
>Is this legal? It is if X is derived from Y, but that involves knowing
>the complete types.
>
hmm.. But that is true only in the definition of the function because
the compiler would want to generate code that will look at the runtime type of
the exception and then decide weather to call unexpeced() or not.
as far as the decleration of the function is concerned I can think of no
reason why the complete type is required.

The rules for arguments to functions is already similar

class T;
void foo (T);   // is legal but
void foo(T) {} //  is not legal T is an incomplete type

so why is
class T;
void foo() throw(T) ; // not legal??

cheers
-bom
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Ravikant Iyer <bom@slip.net>
Date: 1997/05/30
Raw View
Alexandre Oliva <oliva@dcc.unicamp.br> writes:
>
>
> struct base { virtual void foo() throw(X); };
> struct derived : public base { void foo() throw(Y); };
>
> Is derived::foo acceptable?  It should only be considered valid if Y
> is certainly unambiguously derived from X.  If Y is an incomplete
> type, though, the compiler can't tell, and the decision would have to
> be left for runtime.  If foo is going to propagate an exception, it
> must ensure that such an exception is both an X and a Y.  Now imagine
> a deep inheritance hierarchy with dozens of exception specifications
> for each member function in each level!
>
> Although implementing that check at run-time is possible (as far as I
> can see), it is too costly if the complete types are not known at
> compile time.
>

I understand that defering such checks untill runtime might not be very
effecient but the rules could have been similar to return types on virtual
functions. i.e.

class T;

struct X { virtual T &foo ();}
struct Y : struct X {T &foo ();}

is perfectly legal, but iff the type is different in the derived class then
a pointer or referance to a complete type is required. e.g.

class T;
class U;
struct X { virtual U &foo ();}
struct Y : struct X {U &foo ();} // not allowed U is incomplete..

>
> Another problem of allowing this check to be delayed to runtime is
> that it may have unexpected interactions with the One Definition Rule.
> Some functions are allowed to be given multiple definitions in
> different translation units that compose a program, as long as these
> definitions are exactly the same, as stated in [basic.def.odr].  If,
> at the point of definition of such a function in one translation unit
> X and Y are complete types, the check can be performed at
> compile-time; in another, where X and Y are incomplete types, the
> check is delayed to runtime.  Now you have two different versions of
> the same function, just because in one of them a type was defined and
> in another it was not.
>
Decleration and Definition of functions are treated differently any way..
so the rules could always require that the any exception specifications
in the definition of functions should have only complete types.. This is
the rule for function arguments any ways.. e.g.

class T;

void foo (T); // is legal
but
void foo (T) {} // is not legal..

> This might lead to one of two requirements: any function that might be
> given multiple definitions and has an exception specification must
> have exactly the same set of exception types complete and incomplete
> than in any other translation unit (and it would be quite hard to
> require a diagnostic for that), or the decision must always be delayed
> to runtime in such functions.
>

I definetely would not like to see this whole checking moved to run time,
but I feel that relaxing the compile time requirements some more so
as to require complete type definitions only where it is really needed would
be more in line with the rest of the rules of the language..

cheers
-bom
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Michael Ball <michael.ball@eng.sun.com>
Date: 1997/06/03
Raw View
John (Max) Skaller wrote:
>
> On 28 May 1997 22:24:19 PDT, Ravikant Iyer <bom@slip.net> wrote:
>
> >15.4 [except.spec] para 1 prohibits from incomplete types in
> >exception-specifications. I was wondering what could be the reason for this.
>
> I personally believe this is a mistake of an overworked committee.
>

You may be right, or at least that's as good a suggestion as
any.  I believe that completeness at the definition is necessary,
completeness at the call can allow better optimization and better
error checking. Completeness at the declaration is silly.

However, I stopped arguing about it and supported the current
restriction because it just didn't seem very important in actual
programs.

Why? You may well ask.

Well, essentially every actual exception-using program that I've
seen has defined a (relatively) small hierarchy of (relatively)
simple exception classes, and has usually defined most of them
in a single header. Thus in most programs all the we have
mandated is the inclusion of a single relatively small header file.

I know, this may be true only because existing implementations
are poor, and so on.  None the less, I think that even with the
restriction there is a reasonable style of programming that doesn't
impose terribly on the programmer.

Perhaps your suggestion of exhaustion IS the correct one. :-)

-Mike Ball-
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Ravikant Iyer <bom@slip.net>
Date: 1997/05/28
Raw View
hi,

15.4 [except.spec] para 1 prohibits from incomplete types in
exception-specifications. I was wondering what could be the reason for this.

This prevents me from writing code like this..

class Exception1;
class Exception2;

struct foo
{
 void foo1() throw (Exception1);
 void foo2() throw (Exception2);
};

This means that any one who uses the header in which foo is defined would
have to drag along definitions for _all_ classes used in all the exception
specifications in that one file.. If a particular module wants to use foo1
to only call foo1 member function then that module has no use for the
definition of Exception2.

Can someone please shed some light on the topic

thanks in advance
-bom
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]