Topic: const_cast and throw( ) clauses
Author: smeyers@teleport.com (Scott Meyers)
Date: 1996/10/13 Raw View
In article <32594DB9.1648@elastic.avid.com>,
Garth A. Dickie <dickie@fantasia.avid.com> wrote:
| Apparently a throw( ) clause is part of a function's type, so that we
| can write:
|
| typedef void ( * ProgressMeterCallback )( double amountDone ) throw( );
Ah, last I checked, we can't, but thank you for the opportunity to bring
this up once again. I posted the following on April 30 and got no
response, so I posted it again on July 22, and again I got no response.
This makes my third posting, and would somebody who knows something PLEASE
say something about this? This is important, and not just because the
accuracy of one passage in my book is at stake.
Paul D. DeRocco <pderocco@ix.netcom.com> wrote:
| Jack Reeves wrote:
| > Can anyone explain why the DWP explicity disallows exception
| > specifications on a typedef?
|
| Because it's not part of the type. And a good thing too, since exception
| specs are far more likely to change in a library routine than the actual
| arg and return types.
Exception specs may not technically be part of a function's type, but note
that they are checked in many cases. From DWP 15.4:
2 If any declaration of a function has an exception-specification, all
declarations, including the definition, of that function shall have an
exception-specification with the same set of type-ids. If a virtual
function has an exception-specification, all declarations, including
the definition, of any function that overrides that virtual function
in any derived class shall have an exception-specification at least as
restrictive as that in the base class. [Example:
struct B {
virtual void f() throw (int, double);
virtual void g();
};
struct D: B {
void f(); // ill-formed
void g() throw (int); // OK
};
--end example] The declaration of D::f is ill-formed because it
allows all exceptions, whereas B::f allows only int and double. Simi-
larly, any function or pointer to function assigned to, or initializ-
ing, a pointer to function shall have an exception-specification at
least as restrictive as that of the pointer or function being assigned
to or initialized. [Example:
void (*pf1)(); // no exception specification
void (*pf2) throw(A);
void f()
{
pf1 = pf2; // ok: pf1 is less restrictive
pf2 = pf1; // error: pf2 is more restrictive
}
--end example]
3 In such an assignment or initialization, exception-specifications on
return types and parameter types shall match exactly.
4 In other assignments or initializations, exception-specifications
shall match exactly.
Given that the syntax of function pointers is one of the best arguments for
typedefs and given that exception specs are checked during initialization
and assignment of function pointers, the explicit restriction against the
use of exception specs in typedefs seems almost cruel. Unless there is a
better argument against allowing exception specs in typedefs, I think the
prohibition should be reconsidered.
Scott
--
Scott Meyers, Ph.D. Voice: 503/638-6028
C++ Consulting and Training Fax: 503/638-6614
Author of "Effective C++" Email: smeyers@netcom.com
and "More Effective C++" WWW: http://www.teleport.com/~smeyers
[ 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: "Garth A. Dickie" <dickie@fantasia.avid.com>
Date: 1996/10/07 Raw View
Apparently a throw( ) clause is part of a function's type, so that we
can write:
typedef void ( * ProgressMeterCallback )( double amountDone ) throw( );
Then the following will be a compile-time error:
void Compute( ..., ProgressMeterCallback progressMeterCallback ) { }
void OopsCallback( double amountDone ) { }
Compute( ..., OopsCallback ) // error -- OopsCallback needs throw( ) clause.
I would like to know what cast can be used to remove or change
the throw( ) clause part of a function pointer. The natural place
for this seems to be const_cast. If it is not already possible, I
would like to propose that it be made possible.
If you know in a given context that OopsCallback will not throw
any exception, you can then write
Compute( ..., const_cast< ProgressMeterCallback >( OopsCallback )) // no error
Just as with const_cast used to cast away const or volatile, the
types must match except in their const, volatile, or throw( ) qualifiers.
In addition, a static_cast will not allow the removal or weakening of a
throw( ) qualifier.
Comments? Is this already in there and I didn't know it? Are there any
problems with this approach?
Regards,
Garth A. Dickie
[ 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 ]