How on earth did noexcept get through the standards process?

321 views
Skip to first unread message

Andrew

unread,
Mar 14, 2011, 2:17:04 PM3/14/11
to

I have just come across the new noexcept feature and I am horrified.

Once upon a time I was very keen indeed on full statically checked
exception specifications. And by that I mean full proper checks, not
the weedy kind that will be deprecated. I proposed this in a
discussion paper, way back in 2001. See
http://www.andrewpetermarlow.co.uk/goodies/proposal.pdf.
Writing this paper made me think about the issue alot and eventually I
withdrew the proposal.

As I came to see it, there were just too many difficulties and not
enough benefit. The main difficulty is that when using such exception
speciifcations, exceptions become single level propagation. They also
have extremely limited use in the presence of templates, which makes
them unsuitable for many parts of the standard library. Since those
days I entered the world of java and my experiences there just confirm
the conclusion I came to. I think Bruce Eckel sums it up very well in
his article http://www.mindview.net/Etc/Discussions/CheckedExceptions
where he says that checked exceptions in java are a failed experiment.

So why on earth do we have noexcept? And given that it is there, why
are the checks not strict? It is the lack of strictness that seems to
be causing the controversy, i.e. undefined behaviour versus
std::terminate. I reckon the answer is that old chestnut, premature
optimization is the root of all evil.

Discuss!

Andrew M.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

itaj sherman

unread,
Mar 14, 2011, 7:31:13 PM3/14/11
to

On Mar 14, 8:17 pm, Andrew <marlow.and...@gmail.com> wrote:
> I have just come across the new noexcept feature and I am horrified.
>

>

> So why on earth do we have noexcept? And given that it is there, why
> are the checks not strict? It is the lack of strictness that seems to
> be causing the controversy, i.e. undefined behaviour versus
> std::terminate. I reckon the answer is that old chestnut, premature
> optimization is the root of all evil.
>
> Discuss!
>

There are two main different kinds of "exception specification" for a
function:
1) "requests" - the programmer requests the compiler to verify that
the function applies to them (in some certain defined ways at compile
and/or runtime).
2) "promises" - the programmer promises that the function applies,
allowing the compiler to assume so for whatever it does (that can help
exception safety concept checking, and optimization).

The old specifications where of the first kind, and for various
reasons many people concluded they do more harm then good (especially
for performance critical languages).
The noexcept is of the second kind. More specifically, allowing only a
yes/no specification rather than exception type specific. The
programmer promises that the function throws nothing, the compiler is
allowed to assume so for whatever it does. The implementation is also
allowed to check that if they want, but generally they don't have to
do so, so that they don't cause unnecessary runtime overhead.

If I read it right, your ex-proposal discusses specifications of the
first kind "requests", so whether incorporating noexcept isn't much
related.

itaj

Nevin :-] Liber

unread,
Mar 15, 2011, 6:37:44 AM3/15/11
to
In article <bd9d80b3-3526-41e0...@i39g2000prd.googlegroups.com>,
itaj sherman <itajs...@gmail.com> wrote:

> The noexcept is of the second kind. More specifically, allowing only a
> yes/no specification rather than exception type specific. The
> programmer promises that the function throws nothing, the compiler is
> allowed to assume so for whatever it does. The implementation is also
> allowed to check that if they want, but generally they don't have to
> do so, so that they don't cause unnecessary runtime overhead.

They have to check, and call std::terminate if an exception is thrown
from a function declared noexcept(true). See 15.5.1 in n3242 (the
latest draft) for details.

--
Nevin ":-)" Liber <mailto:ne...@eviloverlord.com> 773 961-1620

Andy Venikov

unread,
Mar 15, 2011, 6:35:55 AM3/15/11
to
On 03/14/2011 07:31 PM, itaj sherman wrote:
<snip>

> The noexcept is of the second kind. More specifically, allowing only a
> yes/no specification rather than exception type specific. The
> programmer promises that the function throws nothing, the compiler is
> allowed to assume so for whatever it does. The implementation is also
> allowed to check that if they want, but generally they don't have to
> do so, so that they don't cause unnecessary runtime overhead.

Well, actually not...
15.4.9 of the latest N3242 says that throwing from noexcept will result
in a call to std::terminate. So the compiler may not ignore noexcept()
sepcification and must insure that if any exception is trying to
propagate from noexcept function, terminate() will be called.
It smells just like throw(). Are we getting into the same quagmire?

Other than being able to test at compile time if a function was
noexcept-ed (which is yes, useful), I don't see much improvement over
throw(). Compiler will still have to insert extra code to noexcept
functions. Was that the intent?

Thanks,
Andy.


P.S. The only explanation I can think of is that the implementors came
back and said that noexcept feature will somehow perform on par with
regular functions. I guess it can be done.

Andrew

unread,
Mar 15, 2011, 6:48:02 AM3/15/11
to
On Mar 14, 11:31 pm, itaj sherman <itajsher...@gmail.com> wrote:
> On Mar 14, 8:17 pm, Andrew <marlow.and...@gmail.com> wrote:
>
> > I have just come across the new noexcept feature and I am horrified.
>
> > So why on earth do we have noexcept? And given that it is there, why
> > are the checks not strict?

> There are two main different kinds of "exception specification" for a


> function:
> 1) "requests" - the programmer requests the compiler to verify that
> the function applies to them (in some certain defined ways at compile
> and/or runtime).
> 2) "promises" - the programmer promises that the function applies,
> allowing the compiler to assume so

[snip]

> The noexcept is of the second kind.

> If I read it right, your ex-proposal discusses specifications of the


> first kind "requests", so whether incorporating noexcept isn't much
> related.

Err, yes, you're right. And I suppose that noexcept is of the second
kind partly because it is so hard to do the static check fully, I as
found out when writing my proposal.

Another thing I hadn't fully appreciated is that the implementation of
noexcept can detect the violation at the point of throwing rather than
at catch point. Detecting at the catch point would defeat the kind of
optimisation which is the whole point of noexcept. Detecting at throw
point allows stack unwinding to be optional before std::terminate is
called.

I have been thinking about noexcept because a colleague has drawn my
attention to N3248, where the issue of testing noexcept functions is
discussed. N3248 argues that when noexcept is violated it should be
undefined behaviour, rather than calling std::terminate. It is said
that UB gives the implementer of noexcept functions the freedom to
define behaviour in the case of debug mode builds such that
precondition assertion failures can be detected and handled in a unit
test harness.

My inclination is that a test harness that is trying to test that
precondition violation of noexcept functions is working properly needs
to override the default handler for std::terminate. Their handler can
integrate with their unit test framework.

Regards,

Andrew Marlow

DeMarcus

unread,
Mar 15, 2011, 6:50:35 AM3/15/11
to


With noexcept the compiler can help you provide exception guarantees. See

http://www.boost.org/community/exception_safety.html


Regards,
Daniel

itaj sherman

unread,
Mar 15, 2011, 10:34:13 PM3/15/11
to

On Mar 15, 12:48 pm, Andrew <marlow.and...@gmail.com> wrote:

>
> I have been thinking about noexcept because a colleague has drawn my
> attention to N3248, where the issue of testing noexcept functions is
> discussed. N3248 argues that when noexcept is violated it should be
> undefined behaviour, rather than calling std::terminate. It is said
> that UB gives the implementer of noexcept functions the freedom to
> define behaviour in the case of debug mode builds such that
> precondition assertion failures can be detected and handled in a unit
> test harness.
>

Core language issue 1053 2010-3 seems to be exactly about this:
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1053

it seems to have rejected the unspecified behaviour for throwing from
a noexcept function. I hope N3248 can change things now for the
better.

itaj

itaj sherman

unread,
Mar 15, 2011, 10:32:02 PM3/15/11
to

On Mar 15, 12:37 pm, "Nevin :-] Liber" <ne...@eviloverlord.com> wrote:
> In article <bd9d80b3-3526-41e0-a8bb-5c685abbf...@i39g2000prd.googlegroups.com>,

> itaj sherman <itajsher...@gmail.com> wrote:
>
>> The noexcept is of the second kind. More specifically, allowing only a
>> yes/no specification rather than exception type specific. The
>> programmer promises that the function throws nothing, the compiler is
>> allowed to assume so for whatever it does. The implementation is also
>> allowed to check that if they want, but generally they don't have to
>> do so, so that they don't cause unnecessary runtime overhead.
>
> They have to check, and call std::terminate if an exception is thrown
> from a function declared noexcept(true). See 15.5.1 in n3242 (the
> latest draft) for details.
>

OMG, I had some big misconception about noexcept. It actually does
belong to the "request" kind of exception specifications.
I can't remember now when it was that I read about this and got
convinced that this was the point of the difference between noexcept
and throw(), but it's apparantly wrong. I was so sure that was the
whole point of noexcept that I didn't even bother to check it again.

Well then, if noexcept actually does force the compiler to add runtime
checking, then I truely agree with the OP really how on earth did it
get through the standard process?

itaj


--

James Kanze

unread,
Mar 15, 2011, 10:34:07 PM3/15/11
to

On Mar 14, 11:31 pm, itaj sherman <itajsher...@gmail.com> wrote:
> On Mar 14, 8:17 pm, Andrew <marlow.and...@gmail.com> wrote:

>> I have just come across the new noexcept feature and I am horrified.

>> So why on earth do we have noexcept? And given that it is there, why
>> are the checks not strict? It is the lack of strictness that seems to
>> be causing the controversy, i.e. undefined behaviour versus
>> std::terminate. I reckon the answer is that old chestnut, premature
>> optimization is the root of all evil.

>> Discuss!

> There are two main different kinds of "exception specification" for a
> function:
> 1) "requests" - the programmer requests the compiler to verify that
> the function applies to them (in some certain defined ways at compile
> and/or runtime).
> 2) "promises" - the programmer promises that the function applies,
> allowing the compiler to assume so for whatever it does (that can help
> exception safety concept checking, and optimization).

> The old specifications where of the first kind, and for
> various reasons many people concluded they do more harm then
> good (especially for performance critical languages).

Actually, the performance impact on most platforms was zero.

> The noexcept is of the second kind. More specifically, allowing only a
> yes/no specification rather than exception type specific. The
> programmer promises that the function throws nothing, the compiler is
> allowed to assume so for whatever it does. The implementation is also
> allowed to check that if they want, but generally they don't have to
> do so, so that they don't cause unnecessary runtime overhead.

In other words, the introduce yet another case of undefined
behavior. I've not looked at them in detail, but if that's the
case, I'm against them.

The old ones actually worked pretty well. They provided perhaps
more than was needed---it's hard to think of a case where
anything other than throw() was appropriate. But at least when
you wrote throw(), you had a guarantee.

--
James Kanze

Goran

unread,
Mar 15, 2011, 10:33:46 PM3/15/11
to

On Mar 14, 7:17 pm, Andrew <marlow.and...@gmail.com> wrote:
> I have just come across the new noexcept feature and I am horrified.
>
> Once upon a time I was very keen indeed on full statically checked
> exception specifications. And by that I mean full proper checks, not
> the weedy kind that will be deprecated. I proposed this in a
> discussion paper, way back in 2001. Seehttp://www.andrewpetermarlow.co.uk/goodies/proposal.pdf.

> Writing this paper made me think about the issue alot and eventually I
> withdrew the proposal.
>
> As I came to see it, there were just too many difficulties and not
> enough benefit. The main difficulty is that when using such exception
> speciifcations, exceptions become single level propagation. They also
> have extremely limited use in the presence of templates, which makes
> them unsuitable for many parts of the standard library. Since those
> days I entered the world of java and my experiences there just confirm
> the conclusion I came to. I think Bruce Eckel sums it up very well in
> his articlehttp://www.mindview.net/Etc/Discussions/CheckedExceptions

> where he says that checked exceptions in java are a failed experiment.
>
> So why on earth do we have noexcept? And given that it is there, why
> are the checks not strict? It is the lack of strictness that seems to
> be causing the controversy, i.e. undefined behaviour versus
> std::terminate. I reckon the answer is that old chestnut, premature
> optimization is the root of all evil.

Well, I personally am +/- happy with this explanation (http://
www.codeguru.com/cpp/misc/print.php/c18357/An-Interview-with-C-Creator-Bjarne-Stroustrup.htm):

"noexcept addresses the one case where the exception specifications
sometimes worked well: simply stating that a function is not supposed
to throw. In C++98, some people express that by saying throw(), but
they can not know whether their implementation then imposed a
significant overhead (some do) and might end up executing a
(potentially unknown) unexpected handler. With noexcept a throw is
considered a fatal design error and the program immediately
terminated. That gives security and major optimization opportunities."

To me, optimization is just fine as a reason. Currently, we are (well,
I am, at least) writing sections of code that I know must never throw
(and if they do, I must fix them), and use no exception spec (boost
guys do the same, see "never throws" comments in their code). With
nothrow, I can move those into a function and reap following benefits:

* mark that "nothrow" presumption more clearly,
* benefit from optimization.

With old throw(), that wasn't possible in the same manner (albeit at
least one well-known compiler coughMScough) ignored what standard
mandated for throw().

So not all is that bad.

Goran.

itaj sherman

unread,
Mar 15, 2011, 10:33:27 PM3/15/11
to

On Mar 15, 12:48 pm, Andrew <marlow.and...@gmail.com> wrote:

>
> I have been thinking about noexcept because a colleague has drawn my
> attention to N3248, where the issue of testing noexcept functions is
> discussed. N3248 argues that when noexcept is violated it should be
> undefined behaviour, rather than calling std::terminate. It is said
> that UB gives the implementer of noexcept functions the freedom to
> define behaviour in the case of debug mode builds such that
> precondition assertion failures can be detected and handled in a unit
> test harness.
>

Yeah, what I meant is exactly what's in this N3248. For some reason I
was sure that was the current state of the standard already. Maybe the
missleading wording of 15.4/8 made me think there was this difference:

"A function is said to allow an exception of type E if its dynamic-
exception-specification contains a type T for
which a handler of type T would be a match (15.3) for an exception of
type E."

As this doesn't mention noexcept, this means that a function with
noexcept allows any exception - but the next paragraph that states
when the validation should be done, doesn't use the "function allows"
definition, but resorts to "exception specification allows".

I think this N3248 is an important change. Forcing the compiler to
test for exceptions might cause more overhead than the possible
optimizations can save. I hope it gets accepted before the standard is
concluded, otherwise it will be a backwards-compatibility nightmare to
ever change it in the future.

itaj

SG

unread,
Mar 16, 2011, 7:38:33 AM3/16/11
to

On 14 Mrz., 19:17, Andrew wrote:
> [...]

> Once upon a time I was very keen indeed on full statically checked
> exception specifications. [...]

> Writing this paper made me think about the issue alot and eventually
> I withdrew the proposal.
>
> As I came to see it, there were just too many difficulties and not
> enough benefit. The main difficulty is that when using such exception
> speciifcations, exceptions become single level propagation. They also
> have extremely limited use in the presence of templates, which makes
> them unsuitable for many parts of the standard library. [...]

>
> So why on earth do we have noexcept?

Let me get this straight. Your first paragraph basically says "static
checking is not worth the hassle". Your second paragraph says
"exception specifications are bad". Right?

Since the current incarnation of noexcept does not require any static
checking of whether a function's body *might* violate its noexcept-
specification and since your two examples about the badness of
exception specifications don't seem to apply to the new noexcept
exception specification, I don't see what exactly you are complaining
about.

> And given that it is there, why are the checks not strict?

> [...]
> Discuss!

Are you talking about static checking of the new noexcept exception
specifications? If so, I suggest you start compiling a list of pros
and cons. I would not be surprized if there was some overlap with the
list of pros and cons w.r.t. static checking of *old* exception
specifications. And the latter list obviously made you say something
along the lines of "static checking is not worth the hassle".

Cheers!
SG

itaj sherman

unread,
Mar 16, 2011, 10:42:27 AM3/16/11
to

On Mar 16, 4:34 am, James Kanze <james.ka...@gmail.com> wrote:
> On Mar 14, 11:31 pm, itaj sherman <itajsher...@gmail.com> wrote:

> > There are two main different kinds of "exception specification" for a
> > function:
> > 1) "requests" - the programmer requests the compiler to verify that
> > the function applies to them (in some certain defined ways at compile
> > and/or runtime).
> > 2) "promises" - the programmer promises that the function applies,
> > allowing the compiler to assume so for whatever it does (that can help
> > exception safety concept checking, and optimization).
> > The old specifications where of the first kind, and for
> > various reasons many people concluded they do more harm then
> > good (especially for performance critical languages).
>
> Actually, the performance impact on most platforms was zero.
>

It was?
I mean, they compared code compiled with no-throw optimizations and
runtime checks to the same code with no-throw optimizations without
checks?
Then what makes 'noexcept' better than 'throw()' wrt performance? Is
it just the fact that the compiler knows no exception can be thrown
there (no user defined std::unexcpected can throw anything else and
demand continue execution)?

Actually that makes sense. IMO, practically it still puts 'noexcept'
in what I callled 'promises' kind. I.e Instead the programmer promises
not to throw out of a noexcept function, he can do that, but he knows
the only consequence of it is that the program will end and there's
nothing he can do about it (unlike std::unexpected). These are
practically the same. I still don't see why they bothered to specify
that and not just leave it undefined - but if it doesn't hurt
performance, an important benefit of noexcept IMO, is still there.

itaj

Andrew

unread,
Mar 16, 2011, 5:46:46 PM3/16/11
to

On Mar 16, 2:34 am, itaj sherman <itajsher...@gmail.com> wrote:
> On Mar 15, 12:48 pm, Andrew <marlow.and...@gmail.com> wrote:
>> I have been thinking about noexcept because a colleague has drawn my
>> attention to N3248, where the issue of testing noexcept functions is
>> discussed. N3248 argues that when noexcept is violated it should be
>> undefined behaviour, rather than calling std::terminate. It is said
>> that UB gives the implementer of noexcept functions the freedom to
>> define behaviour in the case of debug mode builds such that
>> precondition assertion failures can be detected and handled in a unit
>> test harness.
>
> Core language issue 1053 2010-3 seems to be exactly about this:http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1053

1053 is closed as not a defect (NAD). The title of 1053 is "Terminate
vs undefined behavior for noexcept violation". Since 1053 is closed I
presume 3248 was raised to resurrect the discussion.

I think the contraversial part of 3248 is the bit where it proposes
support for a debug build mode. Until now I think the only part of the
std that talked about debug mode was the NDEBUG macro as used by the C
assert macro. 3248 would significantly expand the notion of a debug
build versus a release build. This makes me very wary.

My understanding of 3248 is that UB is proposed so that in a debug
build, a noexcept violation can allow an exception to propagate so
that it can be caught and handled by unit test machinery. This allows
tests to be constructed that test what happens when noexcept is
violated and to test that it is violated by move ctors that invoke
throwing operations. I am not sure this is a good idea. Aaprt from
introducing the idea of debug builds into the std, I reckon the aim of
library testability in this area can be acheived another way. How
about the test harness installing its own terminate handler?

> it seems to have rejected the unspecified behaviour for throwing from
> a noexcept function. I hope N3248 can change things now for the
> better.
>
> itaj

I don't see how 3248 changes things for the better. I think that
calling std::terminate instead of it being UB does not inhibit
testing, since the test harness can set its own terminate handler.
Bear in mind that the motivation of 3248 is for library testability.
It is not about performance optimisations. Noexcept is all about
optimisation, as 3248 says:-

"This solution [noexcept] also opens up a long desired optimization
for compilers to exploit, where marking a function that cannot throw
allows the suppression of code to handle exceptional stack unwinding".

So 3248 is not, AFAICS, proposing something that further aids
optimisation. That's not what 3248 is for.

I found other N-items such as 3180 which propose much more extensive
use of noexcept. 3248 seems to be advocating the opposite, as it says:
"The risk from overly aggressive use of noexcept specifications is
that programs with hidden terminate calls are produced". Surely the
implementers of std libraries must have something to say about this. I
wonder what Dinkumware thinks. And the authors of STLPort. I don't
know how Dinkumware, STLPort and any others plan to test this aspect
of their std library implementations (perhaps we should ask them) but
as I have said, one way would be for the test harness to set up its
own terminate handler then invoke a noexcept function that throws.

Regards,

Andrew Marlow

Alexander Terekhov

unread,
Mar 16, 2011, 5:46:18 PM3/16/11
to

Andrew wrote:
[...]


> So why on earth do we have noexcept?

I suppose that the plan is to have noexcept_except() in the next
iteration: The general idea is that an unexpected/uncaught throw will
cause program termination at throw point with core dump recorded at
that point as well. The current noexcept makes all uncaught
downthrows unexpected but that may well be relaxed in the future by
noexcept_except() or some such. (A program calling
noexcept_except(E) may well catch and handle E upcall.)

regards,
alexander.

DeMarcus

unread,
Mar 16, 2011, 5:45:54 PM3/16/11
to

I read the N3248 paper and believe the most clean solution would be something similar to std::atexit.

Create a function std::atnothrow( std::function<void()> ) that will be run whenever a nothrow is violated. The default behavior at violation is std::terminate.

The function taken as argument to std::atnothrow should be an exception handler or exception dispatcher. See

http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.15


Now anyone can override default behavior by doing the following.

std::atnothrow( myNothrowHandler );

static void myNothrowHandler()
{
// Allow any exception.
throw;
}

... or ...

static void myNothrowHandler()
{
// Allow only my logic errors.
try
{
throw;
}
catch( MyLogicErrorException& )
{
throw;
}

std::terminate();
}


/ Daniel

itaj sherman

unread,
Mar 16, 2011, 5:44:35 PM3/16/11
to

On Mar 15, 1:31 am, itaj sherman <itajsher...@gmail.com> wrote:
>> Discuss!
>
> There are two main different kinds of "exception specification" for a
> function:
> 1) "requests" - the programmer requests the compiler to verify that
> the function applies to them (in some certain defined ways at compile
> and/or runtime).
> 2) "promises" - the programmer promises that the function applies,
> allowing the compiler to assume so for whatever it does (that can help
> exception safety concept checking, and optimization).
>

To sum up what everyone corrected about my post:

There are actually 3 kinds:

0) "check and continue" - when a violation of the specification
occurs, the programmer can define a valid way to continue the
execution (in std::unexpected), which can actually be throwing an
exception. That means no-throw optimizations cannot be done at all.
1) "check and die" - when a violation of the specification occurs the
program dies immediately. this forces runtime checks but still allows
no-throw optimizations.
2) "no check" - when a violation of the specification occurs the
behaviour is undefined. this allows no-throw optimizations with no
runtime checks.

'no check' is like my original 'promises'.
'check and continue' and 'check and die' are the important parting if
my original 'requests'.
The point seems to be that the big performance difference is
practically between 'check and continue' and 'check and die'.

So the old 'dynamic-specifications' are of kind 'check and continue',
while 'noexcept' is in 'check and die'.
Core issue 1053 was about moving 'noexcept' further into 'no check'.

Martin B.

unread,
Mar 16, 2011, 6:11:34 PM3/16/11
to

On 16.03.2011 15:42, itaj sherman wrote:
>
> On Mar 16, 4:34 am, James Kanze<james.ka...@gmail.com> wrote:
>> On Mar 14, 11:31 pm, itaj sherman<itajsher...@gmail.com> wrote:
>
>>> There are two main different kinds of "exception specification" for a
>>> function:
>>> 1) "requests" - the programmer requests the compiler to verify that
>>> the function applies to them (in some certain defined ways at compile
>>> and/or runtime).
>>> 2) "promises" - the programmer promises that the function applies,
>>> allowing the compiler to assume so for whatever it does (that can help
>>> exception safety concept checking, and optimization).
>>> The old specifications where of the first kind, and for
>>> various reasons many people concluded they do more harm then
>>> good (especially for performance critical languages).
>>
>> Actually, the performance impact on most platforms was zero.
>>
>
> It was?
> I mean, they compared code compiled with no-throw optimizations and
> runtime checks to the same code with no-throw optimizations without
> checks?
> Then what makes 'noexcept' better than 'throw()' wrt performance? Is
> it just the fact that the compiler knows no exception can be thrown
> there (no user defined std::unexcpected can throw anything else and
> demand continue execution)?
>

As far as I understood it the last time I tried to follow the `noexcept` discussion, the difference is with stack unwinding:
`throw()` needs stack unwinding, wheres `noexcept` doesn't, which somehow makes a big difference.

cheers,
Martin

DeMarcus

unread,
Mar 17, 2011, 7:13:29 AM3/17/11
to
On 2011-03-16 22:44, itaj sherman wrote:
>
> On Mar 15, 1:31 am, itaj sherman<itajsher...@gmail.com> wrote:
>>> Discuss!
>>
>> There are two main different kinds of "exception specification" for a
>> function:
>> 1) "requests" - the programmer requests the compiler to verify that
>> the function applies to them (in some certain defined ways at compile
>> and/or runtime).
>> 2) "promises" - the programmer promises that the function applies,
>> allowing the compiler to assume so for whatever it does (that can help
>> exception safety concept checking, and optimization).
>>
>
> To sum up what everyone corrected about my post:
>
> There are actually 3 kinds:
>
> 0) "check and continue" - when a violation of the specification
> occurs, the programmer can define a valid way to continue the
> execution (in std::unexpected), which can actually be throwing an
> exception. That means no-throw optimizations cannot be done at all.
> 1) "check and die" - when a violation of the specification occurs the
> program dies immediately. this forces runtime checks but still allows
> no-throw optimizations.
> 2) "no check" - when a violation of the specification occurs the
> behaviour is undefined. this allows no-throw optimizations with no
> runtime checks.
>

I don't understand the difference between 0) and 1). In 0) the user can
provide an unexpected handler with std::set_unexpected but in 1) the
user can also provide a handler with std::set_terminate.

Why can 1) do no-throw optimizations but not 0) ?


Thanks,
Daniel

Goran

unread,
Mar 17, 2011, 9:16:15 AM3/17/11
to

On Mar 16, 11:11 pm, "Martin B." <0xCDCDC...@gmx.at> wrote:
> As far as I understood it the last time I tried to follow the `noexcept` discussion,
> the difference is with stack unwinding:
> `throw()` needs stack unwinding, wheres `noexcept` doesn't, which somehow makes a big difference.

That was my understanding, too. ( "Big" in "makes a big difference" is
a big word, though ;-) ).

I find the "OK, but what when noexcept does throw?" question over the
top. UB, end of, what's wrong with that!? There's too many UBs and
gotchas in C and C++ anyhow, and they are already much more surprising
than this one would IMO be. Even the call to std::terminate is too
much there.

Goran.

itaj sherman

unread,
Mar 18, 2011, 4:05:44 AM3/18/11
to

The handler for terminate (default and user) must terminate the
program and never return 18.8.3 (this also means not throw).
So 'noexcept' clearly allows for no-throw optimizations.
As for unexpected, it can actually only throw an exception that is
listed in the dynamic specification 15.4/10. I think it means that
'thow()' also belongs to kind 1 'check and die', and does allow no-
throw optimizations.
It seems that currently 'noexcept' is only better than 'throw()' by
allowing the code to check whether a function is 'noexcept'.

itaj

itaj sherman

unread,
Mar 18, 2011, 4:06:56 AM3/18/11
to
On Mar 17, 3:16 pm, Goran <goran.pu...@gmail.com> wrote:
> On Mar 16, 11:11 pm, "Martin B." <0xCDCDC...@gmx.at> wrote:
>
> > As far as I understood it the last time I tried to follow the `noexcept` discussion,
> > the difference is with stack unwinding:
> > `throw()` needs stack unwinding, wheres `noexcept` doesn't, which somehow makes a big difference.
>
> That was my understanding, too. ( "Big" in "makes a big difference" is
> a big word, though ;-) ).

Does seem so.
http://groups.google.com/group/comp.std.c++/browse_frm/thread/82cd3599ce330676/d41f0839f6d54e5e?q=throw+noexcept+group:comp.*.c%2B%2B*

I didn't get into all the details, but it seems it's mainly
optimizations in the callee (inside the noexcept function) that
benefit from this difference.

>
> I find the "OK, but what when noexcept does throw?" question over the
> top. UB, end of, what's wrong with that!? There's too many UBs and
> gotchas in C and C++ anyhow, and they are already much more surprising
> than this one would IMO be. Even the call to std::terminate is too
> much there.
>

Yeah, this UB would be pretty much straightforward and simple to
understand comparing to many others. I don't see why they need to go
ahead and restrict it for everyone, rather than leave it
implementation defined.

itaj

Agents Marlow

unread,
Mar 18, 2011, 4:10:10 AM3/18/11
to
On Mar 17, 1:16 pm, Goran <goran.pu...@gmail.com> wrote:
> On Mar 16, 11:11 pm, "Martin B." <0xCDCDC...@gmx.at> wrote:
>
> > As far as I understood it the last time I tried to follow the `noexcept` discussion,
> > the difference is with stack unwinding:
> > `throw()` needs stack unwinding, wheres `noexcept` doesn't, which somehow makes a big difference.
>
> That was my understanding, too. ( "Big" in "makes a big difference" is
> a big word, though ;-) ).

I think the point is that noexcept violations are detected and handled
at throw time, saving a stack unwind. throw() violations are detected
at catch time before the function exits, so this is after a stack
unwind has occurred.

> I find the "OK, but what when noexcept does throw?" question over the
> top. UB, end of, what's wrong with that!?

Plenty. It's asymmetric with other contract violations, such as
throw() violations (unexpected) and throwing whilst handling an
exception in progress (terminate). In these cases behaviour is defined
so IMO it should be defined here also. I am in the std::terminate camp
for noexcept violations.

> There's too many UBs and gotchas in C and C++ anyhow,

Indeed, so we do not want to add to the evil thereof.

-Andrew M.

itaj sherman

unread,
Mar 18, 2011, 7:49:46 PM3/18/11
to

And that it is not strict about when and whether stack unwind should
be done (which has been explained to be a cause for performance)

http://groups.google.com/group/comp.std.c++/browse_frm/thread/82cd3599ce330676/d41f0839f6d54e5e?q=throw+noexcept+group:comp.*.c%2B%2B*

James Kanze

unread,
Mar 21, 2011, 12:36:05 AM3/21/11
to
On Mar 16, 2:42 pm, itaj sherman <itajsher...@gmail.com> wrote:
> On Mar 16, 4:34 am, James Kanze <james.ka...@gmail.com> wrote:

> > On Mar 14, 11:31 pm, itaj sherman <itajsher...@gmail.com> wrote:
> > > There are two main different kinds of "exception specification" for a
> > > function:
> > > 1) "requests" - the programmer requests the compiler to verify that
> > > the function applies to them (in some certain defined ways at compile
> > > and/or runtime).
> > > 2) "promises" - the programmer promises that the function applies,
> > > allowing the compiler to assume so for whatever it does (that can help
> > > exception safety concept checking, and optimization).
> > > The old specifications where of the first kind, and for
> > > various reasons many people concluded they do more harm then
> > > good (especially for performance critical languages).

> > Actually, the performance impact on most platforms was zero.

> It was?
> I mean, they compared code compiled with no-throw optimizations and
> runtime checks to the same code with no-throw optimizations without
> checks?

I mean, I compared code with no exception specifications with
code which had exception specifications, and found no
difference.

> Then what makes 'noexcept' better than 'throw()' wrt performance? Is
> it just the fact that the compiler knows no exception can be thrown
> there (no user defined std::unexcpected can throw anything else and
> demand continue execution)?

I don't know. If 'noexcept' gives the same guarantees as
throw(), then I don't see why it's better. About the only real
difference I see is that 'throw()' gives you the option to
specify some exceptions which might pass (and I can imagine that
causes a small performance loss in some special cases), and
noexcept doesn't.

> Actually that makes sense. IMO, practically it still puts 'noexcept'
> in what I callled 'promises' kind.

Both exception specifications (in C++) and noexcept are a
specification of a contract. It's up to the programmer to
respect the contract, or bad things will happen. Other
languages have tried to ensure statically that the contract was
respected, but in practice, that doesn't work too well; regard
the mess Java made of it.

> I.e Instead the programmer promises
> not to throw out of a noexcept function, he can do that, but he knows
> the only consequence of it is that the program will end and there's
> nothing he can do about it (unlike std::unexpected).

You can replaced std::terminate with your own function, and a
programmer wasn't allowed to do much except call std::terminate
in std::unexpected. (He could throw some other exception, which
was allowed, but in the case of 'throw()', no such other
exception exists. Otherwise, he must call terminate.)

> These are practically the same. I still don't see why they
> bothered to specify that and not just leave it undefined - but
> if it doesn't hurt performance, an important benefit of
> noexcept IMO, is still there.

Leave what undefined? (I've not read up on nothrow: if it
doesn't behave exactly like 'throw()', then I'm against it,
since the final behavior in the case of exception specifications
is one thing they got right---even if they aren't too useful
except when empty.)

--
James

James Kanze

unread,
Mar 21, 2011, 12:36:28 AM3/21/11
to
On Mar 16, 10:11 pm, "Martin B." <0xCDCDC...@gmx.at> wrote:
> On 16.03.2011 15:42, itaj sherman wrote:

[...]


> As far as I understood it the last time I tried to follow the
> `noexcept` discussion, the difference is with stack unwinding:
> `throw()` needs stack unwinding, wheres `noexcept` doesn't,
> which somehow makes a big difference.

As far as I understand it (and I've confirmed it with actual
benchmarks with Sun CC under Solaris), stack unwinding only has
a cost if you throw an exception, Not an issue with
noexcept/throw(), since if you throw an exception, you're hosed
anyway. (After all, you promessed not to.)

--
James Kanze

CornedBee

unread,
Mar 21, 2011, 12:32:54 AM3/21/11
to
On Mar 18, 9:05 am, itaj sherman <itajsher...@gmail.com> wrote:
> It seems that currently 'noexcept' is only better than 'throw()' by
> allowing the code to check whether a function is 'noexcept'.

Well, a throw() specification is a "non-throwing specification" as
well, so the noexcept() operator would recognize such a function as
non-throwing.

No, the big advantage of the noexcept specification is that it allows
a compile-time expression as an argument, which makes it useful in
templates such as std::pair (much more useful than throw()).

Also, for Itanium ABI architectures, the code generated for a noexcept
specification is far simpler than for a throw() specification.

Sebastian

Dragan Milenkovic

unread,
Mar 21, 2011, 12:33:51 AM3/21/11
to

Well, I want my core dump in case of a noexcept function throwing
instead of UB (unless my compiler vendor implements this UB
as little men going to the scene of crime and investigating
and submitting the bug report).

--
Dragan

DeMarcus

unread,
Mar 21, 2011, 8:45:15 AM3/21/11
to

Correct me if I'm wrong, but isn't there one more difference; unlike
throw(), noexcept is checked in compile-time so I get a warning or error
if a noexcept function throws?

itaj sherman

unread,
Mar 21, 2011, 11:19:08 AM3/21/11
to

On Mar 21, 6:33 am, Dragan Milenkovic <dra...@plusplus.rs> wrote:

>
> Well, I want my core dump in case of a noexcept function throwing
> instead of UB (unless my compiler vendor implements this UB
> as little men going to the scene of crime and investigating
> and submitting the bug report).
>

In debug/testing version certainly always.
In release version, I suppose usually. But, if the runtime checking
for throw violation has near zero overhead, I'm sure anyone can
imagine a situation so performance critical that he would want the
most efficient implementation possible, possibly ommitting any runtime
check. I don't see why the standard has to impose the runtime check on
all implementations rather than let then decide which option to take.

itaj


--

Felipe Magno de Almeida

unread,
Mar 24, 2011, 2:58:21 AM3/24/11
to
On Mar 21, 12:19 pm, itaj sherman <itajsher...@gmail.com> wrote:
> On Mar 21, 6:33 am, Dragan Milenkovic <dra...@plusplus.rs> wrote:

[snip]

> > Well, I want my core dump in case of a noexcept function throwing
> > instead of UB (unless my compiler vendor implements this UB
> > as little men going to the scene of crime and investigating
> > and submitting the bug report).
>
> In debug/testing version certainly always.
> In release version, I suppose usually. But, if the runtime checking
> for throw violation has near zero overhead, I'm sure anyone can
> imagine a situation so performance critical that he would want the
> most efficient implementation possible, possibly ommitting any runtime
> check. I don't see why the standard has to impose the runtime check on
> all implementations rather than let then decide which option to take.

I feel the same way. I also want a core dump in case I try to use
operator[] with an index which is beyond the vector's size. But I
wouldn't want the standard to impose this overhead to all
implementations. That's why I use a checked STL while debugging
and testing, but define NDEBUG for a few projects in release
(when I can prove that it makes a difference).

With noexcept it is even worse, because even if a function doesn't
throw and the noexcept implementation is not the best for a compiler,
I will have to not use noexcept, which might require some generic
libraries to use the copy-constructor for these types. So we will have
to test it with and without and see which is worse. This is a little
contrary to the "do not pay for what you don't use" in my opinion.
Using and not using noexcept might incur unnecessary overhead.

> itaj

Regards,
--
Felipe Magno de Almeida

ThosRTanner

unread,
Mar 25, 2011, 1:03:40 AM3/25/11
to
On Mar 14, 6:17 pm, Andrew <marlow.and...@gmail.com> wrote:
> I have just come across the new noexcept feature and I am horrified.
>
> Once upon a time I was very keen indeed on full statically checked
> exception specifications. And by that I mean full proper checks, not
> the weedy kind that will be deprecated. I proposed this in a
> discussion paper, way back in 2001. Seehttp://www.andrewpetermarlow.co.uk/goodies/proposal.pdf.
> Writing this paper made me think about the issue alot and eventually I
> withdrew the proposal.
>
(snip)

>
> So why on earth do we have noexcept? And given that it is there, why
> are the checks not strict? It is the lack of strictness that seems to
> be causing the controversy, i.e. undefined behaviour versus
> std::terminate. I reckon the answer is that old chestnut, premature
> optimization is the root of all evil.
>

Where I'm coming from, non-statically checked exception specifications
are completely useless. We can't afford a program crashing because it
threw an exception it wasn't meant to.

And this doesn't help things at all.

As far as I can see they've just dropped the ability to specify what
exceptions you think you might throw and offered no significant
benefits (apart presumably from the checking being quicker)


--

Alexander Terekhov

unread,
Mar 25, 2011, 12:00:48 PM3/25/11
to

Felipe Magno de Almeida wrote:
[...]


> I feel the same way. I also want a core dump in case I try to use
> operator[] with an index which is beyond the vector's size. But I
> wouldn't want the standard to impose this overhead to all

That has nothing to do with noexcept. The contention regarding
noexcept() and throw() is what to do if unexpected/unhandled
exception IS thrown: it is given that the cost of detection to
throw is paid already.

regards,
alexander.


--

itaj sherman

unread,
Mar 25, 2011, 12:00:49 PM3/25/11
to

On Mar 25, 7:03 am, ThosRTanner <ttann...@bloomberg.net> wrote:
> On Mar 14, 6:17 pm, Andrew <marlow.and...@gmail.com> wrote:
>
>
>
>
>
>> I have just come across the new noexcept feature and I am horrified.
>
>> Once upon a time I was very keen indeed on full statically checked
>> exception specifications. And by that I mean full proper checks, not
>> the weedy kind that will be deprecated. I proposed this in a
>> discussion paper, way back in 2001. Seehttp://www.andrewpetermarlow.co.uk/goodies/proposal.pdf.
>> Writing this paper made me think about the issue alot and eventually I
>> withdrew the proposal.
>
> (snip)
>
>> So why on earth do we have noexcept? And given that it is there, why
>> are the checks not strict? It is the lack of strictness that seems to
>> be causing the controversy, i.e. undefined behaviour versus
>> std::terminate. I reckon the answer is that old chestnut, premature
>> optimization is the root of all evil.
>
> Where I'm coming from, non-statically checked exception specifications
> are completely useless. We can't afford a program crashing because it
> threw an exception it wasn't meant to.
>

What do you expect it to do then? How could it not crash?
For exampe, cosider the swap overload for some class that is used as
element of containers with move semantics. swap has to be marked
noexcept, but what do you expect to happen if it actually throws
something at runtime?
The state of the container will probabely be broken, as its code
assumes that the element's swap doesn't throw. There's no way you
could allow the execution to continue.

itaj

Martin B.

unread,
Mar 27, 2011, 4:04:56 AM3/27/11
to
On 25.03.2011 06:03, ThosRTanner wrote:
> On Mar 14, 6:17 pm, Andrew<marlow.and...@gmail.com> wrote:
>> I have just come across the new noexcept feature and I am horrified.
>>
>> Once upon a time I was very keen indeed on full statically checked
>> exception specifications. And by that I mean full proper checks, not
>> the weedy kind that will be deprecated. I proposed this in a
>> discussion paper, way back in 2001. Seehttp://www.andrewpetermarlow.co.uk/goodies/proposal.pdf.
>> Writing this paper made me think about the issue alot and eventually I
>> withdrew the proposal.
>>
> (snip)
>>
>> So why on earth do we have noexcept? And given that it is there, why
>> are the checks not strict? It is the lack of strictness that seems to
>> be causing the controversy, i.e. undefined behaviour versus
>> std::terminate. I reckon the answer is that old chestnut, premature
>> optimization is the root of all evil.
>>
>
> Where I'm coming from, non-statically checked exception specifications
> are completely useless. We can't afford a program crashing because it
> threw an exception it wasn't meant to.
>

Then simply don't use exception specifications.

My impression so far is (no detailed checking done on my part), that the
places where the std library mandates them, your app would already have
crashed or invoked UB if the noexcept clauses that are required by the
current draft weren't there.

> And this doesn't help things at all.
>
> As far as I can see they've just dropped the ability to specify what
> exceptions you think you might throw and offered no significant
> benefits (apart presumably from the checking being quicker)
>

Well, the checking/handling presumably generates less overhead and
facilitates more optimization opportunies, which should be a Good Thing.

As for std::terminate ... you can customize it's behaviour (a bit):

http://www.cplusplus.com/reference/std/exception/set_terminate/

cheers,
Martin

Daniel Krügler

unread,
Mar 28, 2011, 7:29:25 PM3/28/11
to

On 2011-03-21 13:45, DeMarcus wrote:
>
> Correct me if I'm wrong, but isn't there one more difference; unlike
> throw(), noexcept is checked in compile-time so I get a warning or error
> if a noexcept function throws?

In either case the compiler might give a warning, because it is allowed ;-) Seriously, since both behaviours are runtime-defined ending up in very similar effects, I see no reason, why a compiler should warn differently in either

void foo() throw() {
throw 42;
}

compared to

void foo() noexcept {
throw 42;
}

HTH & Greetings from Bremen,

Daniel Krügler

DeMarcus

unread,
Mar 29, 2011, 9:41:13 PM3/29/11
to
On 03/29/2011 01:29 AM, Daniel Krügler wrote:
>
> On 2011-03-21 13:45, DeMarcus wrote:
>>
>> Correct me if I'm wrong, but isn't there one more difference; unlike
>> throw(), noexcept is checked in compile-time so I get a warning or error
>> if a noexcept function throws?
>
> In either case the compiler might give a warning, because it is allowed
> ;-) Seriously, since both behaviours are runtime-defined ending up in
> very similar effects, I see no reason, why a compiler should warn
> differently in either
>
> void foo() throw() {
> throw 42;
> }
>
> compared to
>
> void foo() noexcept {
> throw 42;
> }
>

I thought we would have compile-time checks for noexcept, giving us a
compiler error in your last example.

I looked into N2855. (If there's a better paper on noexcept, please tell me)

http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2855.html#noexcept-block

In N2855 they would have solved your last example like this.

void foo() noexcept {
noexcept { throw 42; }
}

Then we can let the compiler do compile-time checks as well as having
run-time checks where the user wants.

Why can't we have the compile-time checks?

Thanks,

CornedBee

unread,
Mar 29, 2011, 9:51:33 PM3/29/11
to
On Mar 29, 1:29 am, Daniel Krügler <daniel.krueg...@googlemail.com>
wrote:

> On 2011-03-21 13:45, DeMarcus wrote:
>
>
>
> > Correct me if I'm wrong, but isn't there one more difference; unlike
> > throw(), noexcept is checked in compile-time so I get a warning or error
> > if a noexcept function throws?
>
> In either case the compiler might give a warning, because it is allowed ;-)

But you won't get an error. In fact, the standard explicitly forbids
the compiler from failing compilation:

[except.spec]p11: "An implementation shall not reject an expression
merely because when executed it throws or might throw an exception
that the containing function does not allow."

Sebastian

Daniel Krügler

unread,
Mar 30, 2011, 6:37:34 PM3/30/11
to

On 2011-03-30 03:41, DeMarcus wrote:
> On 03/29/2011 01:29 AM, Daniel Krügler wrote:
>>
>> On 2011-03-21 13:45, DeMarcus wrote:
>>>
>>> Correct me if I'm wrong, but isn't there one more difference; unlike
>>> throw(), noexcept is checked in compile-time so I get a warning or error
>>> if a noexcept function throws?
>>
>> In either case the compiler might give a warning, because it is allowed
>> ;-) Seriously, since both behaviours are runtime-defined ending up in
>> very similar effects, I see no reason, why a compiler should warn
>> differently in either
>>
>> void foo() throw() {
>> throw 42;
>> }
>>
>> compared to
>>
>> void foo() noexcept {
>> throw 42;
>> }
>>
>
> I thought we would have compile-time checks for noexcept, giving us a
> compiler error in your last example.

A compiler is *required* to accept this program, see 15.4 p. 11 in N3242:

"An implementation shall not reject an expression merely because when executed it throws or might throw an exception that the containing function does not allow."

> I looked into N2855. (If there's a better paper on noexcept, please tell
> me)

This was one of the first proposal papers, but is very different from what finally became accepted. See

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3050.html

for the finally accepted paper.

> http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2855.html#noexcept-block
>
> In N2855 they would have solved your last example like this.
>
> void foo() noexcept {
> noexcept { throw 42; }
> }
>
> Then we can let the compiler do compile-time checks as well as having
> run-time checks where the user wants.
>
> Why can't we have the compile-time checks?

You can ask for them in the future (with new syntax), but there was no consensus to make this change now. Note that the above noexcept syntax does not cover constructor initializer lists, which is a real problem. You can use the noexcept operator to check whether an expression might throw an exception. This feature has been applied to the Standard Library to auto-deduce the effective noexcept-specification especially of special move members and of swap functions, because it solved the problem how containers can work with potentially throwing move operations. Arguably, the syntax is a bit awkward (using noexcept twice) and I believe that in the future we want syntactically simplified forms of this, like noexcept(auto) as described in

http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2010/n3207.htm

or some such. For a bit more about the rationale for the decisions regarding noexcept and C++0x see e.g.

http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2010/n3202.pdf

The fact that even after the current noexcept specification in the current working paper considerable improvement suggestions have been made, e.g. in

http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2010/n3227.html

implies to me that noexcept might undergo further (backward-compatible) changes and extensions in the future. IMO this is a good thing.

HTH & Greetings from Bremen,

Daniel Krügler


Daniel Krügler

unread,
Mar 30, 2011, 6:36:11 PM3/30/11
to

On 2011-03-30 03:51, CornedBee wrote:
> On Mar 29, 1:29 am, Daniel Krügler<daniel.krueg...@googlemail.com>
> wrote:
>> On 2011-03-21 13:45, DeMarcus wrote:
>>
>>
>>
>>> Correct me if I'm wrong, but isn't there one more difference; unlike
>>> throw(), noexcept is checked in compile-time so I get a warning or error
>>> if a noexcept function throws?
>>
>> In either case the compiler might give a warning, because it is allowed ;-)
>
> But you won't get an error. In fact, the standard explicitly forbids
> the compiler from failing compilation:
>
> [except.spec]p11: "An implementation shall not reject an expression
> merely because when executed it throws or might throw an exception
> that the containing function does not allow."

I'm aware of that. I just wanted to point out, that there is not such a difference between exception specifications using noexcept and throw() as DeMarcus seems to believe (or I have just misread his question). Violation checks for either noexcept or throw() are run-time checks, not compile-time checks. I still expect as a matter of quality of implementation that any compile-time detected violation of these specification will result in a compiler warning - there are easier ways to terminate a program without such distortions.

Greetings from Bremen,

- Daniel Krügler

DeMarcus

unread,
Mar 30, 2011, 6:36:49 PM3/30/11
to

On 03/30/2011 03:51 AM, CornedBee wrote:
> On Mar 29, 1:29 am, Daniel Krügler<daniel.krueg...@googlemail.com>
> wrote:
>> On 2011-03-21 13:45, DeMarcus wrote:
>>
>>
>>
>>> Correct me if I'm wrong, but isn't there one more difference; unlike
>>> throw(), noexcept is checked in compile-time so I get a warning or error
>>> if a noexcept function throws?
>>
>> In either case the compiler might give a warning, because it is allowed ;-)
>
> But you won't get an error. In fact, the standard explicitly forbids
> the compiler from failing compilation:
>
> [except.spec]p11: "An implementation shall not reject an expression
> merely because when executed it throws or might throw an exception
> that the containing function does not allow."
>

I tried the newly released g++ 4.6.0 yesterday and compiled below code.

void fnc() noexcept
{
throw 42;
}

I did not even get a warning. What a disappointment!

It seems I have a lot to learn about noexcept. I would appreciate if someone could explain why the compiler doesn't give me an error on above code, and also why the N2855 paper's noexcept block (see below) is not part of C++0x anymore.

http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2855.html#noexcept-block

void fnc() noexcept
{
// noexcept block
noexcept
{
throw 42;
}
}


Thanks,
Daniel

Martin B.

unread,
Mar 30, 2011, 6:41:07 PM3/30/11
to

On 14.03.2011 19:17, Andrew wrote:
>
> I have just come across the new noexcept feature and I am horrified.
> (...)

>
> So why on earth do we have noexcept? And given that it is there, why
> are the checks not strict? It is the lack of strictness that seems to
> be causing the controversy, i.e. undefined behaviour versus
> std::terminate. I reckon the answer is that old chestnut, premature
> optimization is the root of all evil.
>

This article has been the best explanation I have found so far:
The Debate on noexcept (Apr 2010, ...)
http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=481
http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=482
http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=483

Note that its author, Danny Kalev, draws the same conclusion, namely that "Premature optimization is evil, as we all know too well."

My personal opinion on the matter is split, but let me highlight some quotes from the article which might shed some light on some issues raised in this thread:

How Does noexcept Differ from throw()?

... the proposal requires that in the
event of a noexcept violation, the
implementation shall call terminate() ...
More specifically, the implementation
shall *not* invoke local objects'
destructors if a noexcept violation has
occurred.

...
Why noexcept is Needed

The proponents of noexcept claim that
marking certain functions as noexcept
may improve performance -- especially
in Standard Library algorithms and
containers, as opposed to using throw().
The deprecated throw() exception
specification forces the compiler to
generate auxiliary code to intercept
runtime violations ...
As opposed to throw(), noexcept allows
the compiler to forego the generation
of that auxiliary code. As a result,
the compiler can generate code that's
more efficient -- both the code of the
function flagged as noexcept, and the
code that calls such a function.

I think this two snippets pretty much sum up what noexcept is supposed to provide. Whether it succeeds at this apparently remains to be seen.

cheers,
Martin

Alexander Terekhov

unread,
Mar 31, 2011, 1:50:08 PM3/31/11
to

"Martin B." wrote:

[... quoting Danny Kalev ...]

> How Does noexcept Differ from throw()?
>
> ... the proposal requires that in the
> event of a noexcept violation, the
> implementation shall call terminate() ...
> More specifically, the implementation
> shall *not* invoke local objects'
> destructors if a noexcept violation has
> occurred.

Uhm, "shall *not*" would mean a defined behaviour (and rightfully so).
Sadly, I've heard that a noexcept violation merely triggers undefined
behaviour. It means "may not" instead of "shall not" and it makes
noexcept quite defective in my view.

>
> ...
> Why noexcept is Needed
>
> The proponents of noexcept claim that
> marking certain functions as noexcept
> may improve performance -- especially
> in Standard Library algorithms and
> containers, as opposed to using throw().
> The deprecated throw() exception
> specification forces the compiler to
> generate auxiliary code to intercept
> runtime violations ...
> As opposed to throw(), noexcept allows
> the compiler to forego the generation
> of that auxiliary code. As a result,
> the compiler can generate code that's
> more efficient -- both the code of the
> function flagged as noexcept, and the
> code that calls such a function.

I think that there is no difference between throw() and noexcept for the
code calling non-throwing function, but noexcept is much better than
throw() for the code of the function such flagged due to the relaxation
regading mandatory unwinding in the case of throw().

regards,
alexander.

Daniel Krügler

unread,
Mar 31, 2011, 4:21:10 PM3/31/11
to

Am 31.03.2011 19:50, schrieb Alexander Terekhov:
>
>
> "Martin B." wrote:
>
> [... quoting Danny Kalev ...]
>
>> How Does noexcept Differ from throw()?
>>
>> ... the proposal requires that in the
>> event of a noexcept violation, the
>> implementation shall call terminate() ...
>> More specifically, the implementation
>> shall *not* invoke local objects'
>> destructors if a noexcept violation has
>> occurred.
>
> Uhm, "shall *not*" would mean a defined behaviour (and rightfully so).
> Sadly, I've heard that a noexcept violation merely triggers undefined
> behaviour. It means "may not" instead of "shall not" and it makes
> noexcept quite defective in my view.

While the initial noexcept specification had indeed suggested to make
such violations undefined behaviour, this particular suggestion became
rejected during the Pittsburgh meeting and the revised proposal

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3050.html

became accepted instead. Since then the noexcept-related wording has
undergone only minor changes and in particular the effects of violating
a noexcept exception-specifications are still well-defined to invoke
std::terminate.

HTH & Greetings from Bremen,

Daniel Krügler


Martin B.

unread,
Mar 31, 2011, 4:22:00 PM3/31/11
to

On 31.03.2011 19:50, Alexander Terekhov wrote:
> "Martin B." wrote:
>
> [... quoting Danny Kalev ...]
>
>> How Does noexcept Differ from throw()?
>>
>> ... the proposal requires that in the
>> event of a noexcept violation, the
>> implementation shall call terminate() ...
>> More specifically, the implementation
>> shall *not* invoke local objects'
>> destructors if a noexcept violation has
>> occurred.
>
> Uhm, "shall *not*" would mean a defined behaviour (and rightfully so).
> Sadly, I've heard that a noexcept violation merely triggers undefined
> behaviour. It means "may not" instead of "shall not" and it makes
> noexcept quite defective in my view.
>

Looking at the latest draft N3242[1], p403 §15.5.1/2 we find:
(...) In the situation where the search
for a handler (15.3) encounters the outermost
block of a function with a noexcept-specification
that does not allow the exception (15.4), it
is implementation-defined whether the stack
is unwound, unwound partially, or not unwound at
all before std::terminate() is called. (...)

This would mean *implementation defined* behaviour which is a lot better
than UB. I dare not judge if it would have been better to clearly
specify what must happen, but then, since they chose `terminate()` as
the handler, I'm not sure it matters overmuch in most cases. (And for
those cases where it matters if the stack is unwound, *I guess* either
specification of the standard would probably have been wrong 50% of the
time, so leaving it up to the implementaion seems OK to me.)

>>
>> ...
>> Why noexcept is Needed
>>
>> The proponents of noexcept claim that
>> marking certain functions as noexcept

>> may improve performance (...)


>> more efficient -- both the code of the
>> function flagged as noexcept, and the
>> code that calls such a function.
>
> I think that there is no difference between throw() and noexcept for the
> code calling non-throwing function, but noexcept is much better than
> throw() for the code of the function such flagged due to the relaxation
> regading mandatory unwinding in the case of throw().
>

I think this is platform dependent. As far as I understand exception
handling is implemented significantly different on different platforms
(GCC vs. VC++ / Windows vs. *nix / 32bit arch vs 64 bit arch) that each
*might* benefit on a certain platform.

cheers,
Martin

Seungbeom Kim

unread,
Apr 2, 2011, 6:19:55 PM4/2/11
to

On 2011-03-30 15:41, Martin B. wrote:
>
> This article has been the best explanation I have found so far:
> The Debate on noexcept (Apr 2010, ...)
> http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=481
> http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=482
> http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=483

Thanks for the good articles. It helped me a lot understanding noexcept.

On the other hand, I'm worried about the problems mentioned there,
among which particularly this one:

* /No existing practice./ The committee fell again into the well-known
trap of "design by committee", standardizing a feature that had never
been implemented in the real world. [...]

Were the committee confident that they would do better this time than
they did for export, despite all they learned about "design by committee"?

--
Seungbeom Kim

Patrik Kahari

unread,
Apr 3, 2011, 7:17:19 PM4/3/11
to

>> This article has been the best explanation I have found so far:
>> The Debate on noexcept (Apr 2010, ...)
>> http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=481
>> http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=482
>> http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=483
>
> Thanks for the good articles. It helped me a lot understanding noexcept.
>
> On the other hand, I'm worried about the problems mentioned there,
> among which particularly this one:
>
> * /No existing practice./ The committee fell again into the well-known
> trap of "design by committee", standardizing a feature that had never
> been implemented in the real world. [...]
>
> Were the committee confident that they would do better this time than
> they did for export, despite all they learned about "design by committee"?


Yes that was a good read.

I find it a little bit worrying that the stack is not unwound. At
least with stack unwinding the program is killed gracefully. A program
crash is usually not as bad as leaving a database in some intermediate
state. the program can often be restarted, but the database might not.
It might be impractically hard to manually clean up the database back
to a valid state. Destructors know how to do the right thing, so I
think they should be run. This might be enough for me to avoid using
noexcept . I don't really mind much if that implied a performance cost
as its better to be safe than sorry.

Also that fact that its not specified what should cause an error and
what should cause a warning is not nice. Different compilers may
reject or accept the same code.

Maybe it would have been better to keep noexcept working more like
throw(). We know that works reasonably well.

Cheers, Patrik


--

Martin B.

unread,
Apr 3, 2011, 7:20:01 PM4/3/11
to

On 03.04.2011 00:19, Seungbeom Kim wrote:
>
> On 2011-03-30 15:41, Martin B. wrote:
>>
>> This article has been the best explanation I have found so far:
>> The Debate on noexcept (Apr 2010, ...)
>> http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=481
>> ...

>
> Thanks for the good articles. It helped me a lot understanding noexcept.
>
> On the other hand, I'm worried about the problems mentioned there,
> among which particularly this one:
>
> * /No existing practice./ The committee fell again into the well-known
> trap of "design by committee", standardizing a feature that had never
> been implemented in the real world. [...]
>
> Were the committee confident that they would do better this time than
> they did for export, despite all they learned about "design by committee"?
>

Indeed. I have not seen any explanation on *how* compilers/optimizers will benefit from the introduced `noexcept` semantics:

How will the GCC developers produce better code via noexcept? How will the compiler team at Intel turn `noexcept` into a performance advantage? Will Microsoft ignore it like it did with `throw()` ?

Does anyone know of an article or explanation from compiler implementers that describes how compilers will be able to use the `noexcept` sematics to good effect to produce better code?

cheers,
Martin


--

dietma...@gmail.com

unread,
Apr 4, 2011, 3:04:57 PM4/4/11
to

On Apr 4, 12:20 am, "Martin B." <0xCDCDC...@gmx.at> wrote:
> How will the GCC developers produce better code via noexcept? How will the compiler team at Intel turn `noexcept` into a performance advantage? Will Microsoft ignore it like it did with `throw()` ?
>
> Does anyone know of an article or explanation from compiler implementers that describes how compilers will be able to use the `noexcept` sematics to good effect to produce better code?

Given that the feature was introduced only fairly recently and in
a rush as well, I doubt that there will be much written up on it.
However, I would assume that the main target of the optimizations
is actually the library rather than the compiler. I haven't look
at updating my container implementation, yet, but I can image a
number of places where I could use more efficient approaches if I
don't need to be prepared for recovering after an exception.

Martin B.

unread,
Apr 4, 2011, 3:17:51 PM4/4/11
to

On 04.04.2011 01:17, Patrik Kahari wrote:
>
>>> This article has been the best explanation I have found so far:
>>> The Debate on noexcept (Apr 2010, ...)
>>> http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=481
>>> http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=482
>>> http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=483
>>
>> Thanks for the good articles. It helped me a lot understanding noexcept.
>>
>> On the other hand, I'm worried about the problems mentioned there,
>> among which particularly this one:
>>
>> * /No existing practice./ The committee fell again into the well-known
>> trap of "design by committee", standardizing a feature that had never
>> been implemented in the real world. [...]
>>
>> Were the committee confident that they would do better this time than
>> they did for export, despite all they learned about "design by
committee"?
>
>
> Yes that was a good read.
>
> I find it a little bit worrying that the stack is not unwound. At
> least with stack unwinding the program is killed gracefully. A program
> crash is usually not as bad as leaving a database in some intermediate
> state. the program can often be restarted, but the database might not.
> It might be impractically hard to manually clean up the database back
> to a valid state. Destructors know how to do the right thing, so I
> think they should be run. (...)

Note: The committee choose the `terminate()` function to "handle"
`noexcept` violations. This function is also used to "handle" exceptions
from destructors during stack unwind, and in that case the std even
forbids further stack unwinding. (see below)

So the committee decided to place exceptions from `noexcept` functions
on the same level as exceptions from destructors (during unwind).

cheers,
Martin

p.s.: To quote the std on std::terminate()
# # #
15.5.1 The std::terminate() function
[except.terminate]

1 In some situations exception handling must be
abandoned for less subtle error handling techniques.
[ Note: These situations are:

- ...

- when the exception handling mechanism cannot find
a handler for a thrown exception (15.3), or

- when the search for a handler (15.3) encounters


the outermost block of a function with a

noexceptspecification that does not allow the
exception (15.4), or

- when the destruction of an object during stack
unwinding (15.2) terminates by throwing an exception,
or

- when initialization of a non-local variable with
static or thread storage duration (3.6.2) exits via
an exception, or

- when destruction of an object with static or
thread storage duration exits via an exception
(3.6.3), or

- ...

- when a throw-expression with no operand attempts
to rethrow an exception and no exception is being
handled (15.1), or

- when std::unexpected throws an exception which is
not allowed by the previously violated
dynamicexception- specification, and
std::bad_exception is not included in that
dynamic-exception-specification (15.5.2), or

- ...

- ...

- when execution of the initial function of a thread
exits via an exception (30.3.1.2), or

- ...

-end example ]

2 In such cases, std::terminate() is called
(18.8.3). In the situation where no matching handler
is found, it is implementation-defined whether or
not the stack is unwound before std::terminate() is
called. In the situation where the search for a


handler (15.3) encounters the outermost block of a
function with a noexcept-specification that does not
allow the exception (15.4), it is
implementation-defined whether the stack is unwound,
unwound partially, or not unwound at all before

std::terminate() is called. In all other situations,
the stack shall not be unwound before
std::terminate() is called. ...
# # #

--
Stop Software Patents
http://petition.stopsoftwarepatents.eu/841006602158/
http://www.ffii.org/

Francis Glassborow

unread,
Apr 4, 2011, 3:39:43 PM4/4/11
to

On 30/03/2011 23:36, DeMarcus wrote:

>
> On 03/30/2011 03:51 AM, CornedBee wrote:
>

>> On Mar 29, 1:29 am, Daniel Kr=FCgler<daniel.krueg...@googlemail.com>


>> wrote:
>>
>>> On 2011-03-21 13:45, DeMarcus wrote:
>>>
>>>
>>>
>>> Correct me if I'm wrong, but isn't there one more difference; unlike
>>>> throw(), noexcept is checked in compile-time so I get a warning or
>>>> error
>>>> if a noexcept function throws?
>>>>
>>>
>>> In either case the compiler might give a warning, because it is
>>> allowed ;-)
>>>
>>
>> But you won't get an error. In fact, the standard explicitly forbids
>> the compiler from failing compilation:
>>
>> [except.spec]p11: "An implementation shall not reject an expression
>> merely because when executed it throws or might throw an exception
>> that the containing function does not allow."
>>
>>
> I tried the newly released g++ 4.6.0 yesterday and compiled below code.
>
> void fnc() noexcept
> {
> throw 42;
> }
>
> I did not even get a warning. What a disappointment!
>
> It seems I have a lot to learn about noexcept. I would appreciate if
> someone could explain why the compiler doesn't give me an error on above
> code, and also why the N2855 paper's noexcept block (see below) is not
> part of C++0x anymore.
>
>

I think the first thing to recognise is that after a dozen years exception
specifications in C++ are clearly a failure. The only residual part that
seems potentially useful is throw() (i.e. throws nothing). It would be nice
if that could be statically (i.e. at compile time) checked.

I believe that the motivation behind 'noexcept' was to pull the
functionality of throw() out of exception specifications so that:

1) We can provide more detailed requirements for that case without having t=
o
add verbiage to everywhere that throw specifications are mentioned.

2) Allow the eventual removal of throw specifications (rather like the
human appendix, they do not appear to have any beneficial purpose, but are
only a source of potential problems.

Ideally we would like noexcept to be statically checked. Unfortunately that
would break reams of existing code and seriously inhibit the uptake of
noexcept.

However if the body of a noexcept qualified function does not call
unqualified (i.e. noexcept(false) ) functions and does not itself throw
directly then it becomes possible to optimise its implementation by removin=
g
checks for exceptions and preparation for handling exceptions. (note that
that has implications wrt stack unwinding as the function will no longer be
able to allow an exception to pass through it)

In addition the standard can specify the exception default behaviour for
such things as dtors (as long as it provides a mechanism to allow the
default behaviour to be overruled)

Now the fact that an implementation fails to warn about a manifest breach o=
f
a noexcept qualification is disappointing and I hope that this will soon be
rare. In addition it would be helpful if implementations issued warnings
when they cannot enforce noexcept statically.

I am saddened by the number of people who seem to view noexcept entirely
negatively. Perhaps WG21 is being over-optimistic but it does seem to have
isolated the only place where exception specifications are potentially
useful and provided a mechanism by which this utility can be developed and
encouraged.

Martin B.

unread,
Apr 5, 2011, 12:53:33 PM4/5/11
to

On 04.04.2011 21:39, Francis Glassborow wrote:
>
> On 30/03/2011 23:36, DeMarcus wrote:
>
>>
>> On 03/30/2011 03:51 AM, CornedBee wrote:
>>
>>> On Mar 29, 1:29 am, Daniel Kr=FCgler<daniel.krueg...@googlemail.com>
>>> wrote:
>>>
>>>> On 2011-03-21 13:45, DeMarcus wrote:
>>>>
>>>>
>>>>
>>>> Correct me if I'm wrong, but isn't there one more difference; unlike
>>>>> throw(), noexcept is checked in compile-time so I get a warning or
>>>>> error
>>>>> if a noexcept function throws?
>>>>>
>>>> (...)

>
> I am saddened by the number of people who seem to view noexcept entirely
> negatively. Perhaps WG21 is being over-optimistic but it does seem to have
> isolated the only place where exception specifications are potentially
> useful and provided a mechanism by which this utility can be developed and
> encouraged.
>

Well. This thread seemed to show that a number of people view it
negatively without understanding what it is supposed to (not) do, what's
in the current draft and what other opinions are there on the matter.
(Just as with any other topic I guess.)

I found this discussion very helpful so far as it also forced me to dig
a bit deeper, and all that remains to be seen now is whether the
implementers make good use of `noexcept` :-)

cheers,
Martin

Martin B.

unread,
Apr 5, 2011, 12:53:20 PM4/5/11
to

On 04.04.2011 21:04, dietma...@yahoo.com wrote:
>
> On Apr 4, 12:20 am, "Martin B."<0xCDCDC...@gmx.at> wrote:
>> How will the GCC developers produce better code via noexcept? How will
the compiler team at Intel turn `noexcept` into a performance advantage?
Will Microsoft ignore it like it did with `throw()` ?
>>
>> Does anyone know of an article or explanation from compiler implementers
that describes how compilers will be able to use the `noexcept` sematics to
good effect to produce better code?
>
> Given that the feature was introduced only fairly recently and in
> a rush as well, I doubt that there will be much written up on it.
> However, I would assume that the main target of the optimizations
> is actually the library rather than the compiler. I haven't look
> at updating my container implementation, yet, but I can image a
> number of places where I could use more efficient approaches if I
> don't need to be prepared for recovering after an exception.
>

Do I understand this correctly: The intent would be for the (std)
library implementation to contain (specialized) code to work with (e.g.
move ops) marked as `noexcept` and this code could then be written
differently/more-efficiently from the library code that worked with ops
not marked such?

cheers,
Martin

Bo Persson

unread,
Apr 5, 2011, 5:24:00 PM4/5/11