This is the mail archive of the
gcc-prs@gcc.gnu.org
mailing list for the GCC project.
c++/10457: exception specs vs. -fno-enforce-eh-specs
- From: bkoz at redhat dot com
- To: gcc-gnats at gcc dot gnu dot org
- Cc: mark at codesourcery dot com, jason at redhat dot com
- Date: 23 Apr 2003 03:04:54 -0000
- Subject: c++/10457: exception specs vs. -fno-enforce-eh-specs
- Reply-to: bkoz at redhat dot com
>Number: 10457
>Category: c++
>Synopsis: exception specs vs. -fno-enforce-eh-specs
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Apr 23 03:06:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator: bkoz at redhat dot com
>Release: gcc-3.2.x, gcc-3.3.x, gcc-head
>Organization:
>Environment:
x86/linux RH9
>Description:
This page:
http://gcc.gnu.org/onlinedocs/gcc/C---Dialect-Options.html#C++%20Dialect%20Options
Says that:
-fno-enforce-eh-specs
Don't check for violation of exception specifications at runtime. This option violates the C++ standard, but may be useful for reducing code size in production builds, much like defining NDEBUG. The compiler will still optimize based on the exception specifications.
Seems simple enough. However, this code, which I'd like to use this flag with, won't compile.
#include <stdexcept>
#include <iostream>
struct b
{
virtual void
foo() throw() { }
};
struct c : virtual public b
{
void
foo() { throw std::runtime_error("call unexpected"); }
};
int main()
{
try
{
c obj;
}
catch(std::exception& obj)
{
std::cout << "caught" << std::endl;
std::cout << typeid(obj).name() << std::endl;
}
return 0;
}
This part of the C++ Standard,
15.4 - Exception specifications
gives me the impression that
1) the code above is ill-formed
2) the code above should compile (p10)
3) the code above should throw unexpected when c::foo is called and throws anything (p8)
I'd expect that the above would print out caught, with either the runtime_error or bad_exception type on the thrown object.
That part ok? I'm not quite sure of CWG issues in this area, so bear with me if I don't understand something here.
Anyway.
This behavior, as specified in the standard, is important, and going to get more important in the future (more on that below). If I could specify what g++ did, I'd suggest that
g++ compile this ill-formed code, with an optional warning, and throw unexpected when the exception specs are violated.
For the record, icc-7.0 doesn't get this right either. It doesn't warn (perhaps there is an optional flag) and it doesn't throw.
g++ 3.2.2 does this:
%g++ -fno-enforce-eh-specs xspex.cc
xspex.cc:13: looser throw specifier for `virtual void c::foo()'
xspex.cc:7: overriding `virtual void b::foo() throw ()'
xspex.cc:13: looser throw specifier for `virtual void c::foo()'
xspex.cc:7: overriding `virtual void b::foo() throw ()'
xspex.cc:13: looser throw specifier for `virtual void c::foo()'
xspex.cc:7: overriding `virtual void b::foo() throw ()'
g++ version 3.4 20030420 -fno-enforce-eh-specs
xspex.cc:13: error: looser throw specifier for `virtual void c::foo()'
xspex.cc:7: error: overriding `virtual void b::foo() throw ()'
So. This is important for two reasons:
1) Mark just checked in a patch that supposedly improves compile times when throw() exception specs are used. Jason has also indicated that there are code-size savings.
2) I'd like to add throw() specs to some of the locale facet member functions, to fix things like 10132, and make policy clear.
-benjamin
>How-To-Repeat:
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted: