This is the mail archive of the gcc-prs@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]
Other format: [Raw text]

c++/10457: exception specs vs. -fno-enforce-eh-specs


>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:


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