This is the mail archive of the
gcc-prs@gcc.gnu.org
mailing list for the GCC project.
Re: c++/10457: exception specs vs. -fno-enforce-eh-specs
- From: Jason Merrill <jason at redhat dot com>
- To: nobody at gcc dot gnu dot org
- Cc: gcc-prs at gcc dot gnu dot org,
- Date: 23 Apr 2003 14:26:00 -0000
- Subject: Re: c++/10457: exception specs vs. -fno-enforce-eh-specs
- Reply-to: Jason Merrill <jason at redhat dot com>
The following reply was made to PR c++/10457; it has been noted by GNATS.
From: Jason Merrill <jason at redhat dot com>
To: Benjamin Kosnik <bkoz at redhat dot com>
Cc: gcc-bugs at gcc dot gnu dot org, gcc-prs at gcc dot gnu dot org, mark at codesourcery dot com,
nobody at gcc dot gnu dot org, gcc-gnats at gcc dot gnu dot org
Subject: Re: c++/10457: exception specs vs. -fno-enforce-eh-specs
Date: Wed, 23 Apr 2003 15:14:32 +0100
On Wed, 23 Apr 2003 00:34:40 -0500, Benjamin Kosnik <bkoz at redhat dot com> wrote:
>>You were right when you said that your testcase is ill-formed. The errors
>>g++ is giving are correct, per 15.4p3.
>
> I don't think so.
>
> It's not an assignment or initialization. See my updated comment, where
> d.foo must be called in the try block.
That's irrelevant; the error is the declaration of c::foo. 15.4p3 says,
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 only allow exceptions that are
allowed by the exception-specification of the base class virtual
function.
Thus, c::foo must also be declared throw().
> In any case, 15.4p10, and p8 suggest that this is a runtime error, not a
> compile time error.
15.4p8 deals with runtime behavior, and talks about a function with an
exception specification. c::foo has no exception specification, which is
the problem.
15.4p10 deals with expressions. The problem is with the declaration.
> This blocks the explicitly granted ability of library implementors to
> tighten exception specs.
True. But this also seems problematic: if a library implementor tightens
an exception spec, and a user wants to write a derived class which throws
an exception which would be allowed by the standard, they lose.
It's probably worth raising this conflict in the standards committee,
perhaps as both core and library issues.
>>I suppose that, as an extension, if a derived function has a looser
>>exception specification we could clobber it with the one from the base
>>class and give a pedwarn. But that seems ugly to me.
A more reasonable extension might be to only do this for declarations with
no exception specification at all.
> What happens is that unexpected is called, I don't see this as up for
> debate if we are just interpreting the standard.
Exception specs are enforced in the callee, not the caller. They are a
promise made by a function that a call to that function will not throw an
exception other than those explicitly listed. Since c::foo doesn't have an
exception specification, it never calls unexpected.
The reason for 15.4p3 is so that if I have a b*, I can assume that a call
to bp->foo() will not throw. But if that call finds c::foo instead, and it
throws, we're throwing an exception that we promised not to.
With the current compiler, since b::foo() is declared throw(), unwinding
would fail and we would call terminate(). If b::foo() had some other throw
spec, the exception would escape, violating the exception specification.
> In this case, what unexpected does is implementation defined, and may
> indeed do what you are suggesting, throw bad_exception, etc.
What unexpected does is not implementation defined. For a throw()
specifier, it calls the unexpected handler, which unless changed is
terminate().
> I think the current behavior is wrong. Icc seems to agree.
It looks like icc isn't calling unexpected, either.
Jason