Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How on earth did noexcept get through the standards process?

325 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
to

Martin B. wrote:
> 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?
>

The <utility> section, in addtion to std::move and std::forward, has a
move_if_noexcept() function that helps containers choose between
moving and copying elements. The idea is to move if that is safe, and
fall back to copying if move might throw.

The problem is of course that a container, like std::vector, that has
to reallocate can't survive a throwing move halfway through the
reallocation without losing half its contents.


Bo Persson

--

SG

unread,
Apr 5, 2011, 5:20:13 PM4/5/11
to

On 4 Apr., 21:39, Francis Glassborow wrote:
> [...]

> 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
> removing checks for exceptions and preparation for handling exceptions.

And that is because it is implementation-defined whether stack
unwinding is performed or not as opposed to the violated throw()
specification case where stack unwinding is required. Did I get this
right? If so, yes, that seems to be the only advantage w.r.t.
compilation optimization.

The other and IMHO more important area is that noexcept allows us to
write generic code which can exploit and propagate the noexcept
specification as well as select between two different implementations
to maintain exception safety but also improve performance depending on
whether some type's move constructor might throw or not. Examples:
call wrappers, a growing std::vector.

SG

dietma...@gmail.com

unread,
Apr 6, 2011, 10:34:31 AM4/6/11
to

On Apr 5, 5:53 pm, "Martin B." <0xCDCDC...@gmx.at> wrote:
> 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?

I don't think I said this although it is kind of true: the intent
is to support writing correct (primarily) and potentially more
efficient code. Although compilers may use the information that
something won't throw an exception to apply optimizations, I would
expect that this information is mostly used by libraries. It is
worth noting that the primary motivation for noexecpt is actually
correctness in the sense of preventing reduced exception guarantees
compared to earlier version of the standard: e.g. vector's
push_back() is expected to support the strong guarantee. With
copying we can retain this (we just copy the elements if the range
needs to be resized and throw away the copy if an exception occurs
or the original if everything is copied successfully). If the
objects are movable, we can only retain the strong guarantee if
moving the elements doesn't throw (otherwise we may have moved
some object and we might not be able to move them back). Since in
the new library the vector elements only have to be movable and
not necessarily copyable, this would actually weaken the exception
guarantees: we could only guarantee the basic guarantee. With
knowing whether the objects can be moved without exception, we can
retain the strong guarantee for the types with a noexcept move()
(originally move construction was assumed to be always non-throwing
but this turned out to be too restrictive in some cases).

Whether a call provides the basic or the strong exception guarantee
can be an important correctness issue. Thus, it isn't just
optimizations, at least not directly (on a higher level the approach
may again become an optimization choice, though).

That said, the intend certainly wasn't restricted to be just as a
library feature but I would expect that this is where it is mostly
used: if certain operations are known not to throw, it is possible
to avoid quite a bit of work. This knowledge may also improve the
exception guarantees for some container class templates, depending
on the template parameters: if exception may be thrown everywhere,
it may be essentially infeasible to provide more than the basic
guarantee. However, if there are some operations which are
guaranteed not to throw it can become feasible to provide the
strong or even the no-throw guarantee. The latter aspect may even
propagate out, possibly making substantial areas of code not
throwing any exceptions. Of course, once sections of code are
known not to throw the compiler can also apply magic - just that
I don't know what they are as I'm a library guy.


--

ThosRTanner

unread,
Apr 6, 2011, 3:41:31 PM4/6/11
to

On Mar 25, 5:00 pm, itaj sherman <itajsher...@gmail.com> wrote:
> 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)
>
>
> > 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?

I expect it to not compile. It is possible for the compiler to detect
that a nothrow function is calling a function which might throw.

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

As it (IMO) shouldn't compile, this wouldn't be an issue.

Alexander Terekhov

unread,
Apr 7, 2011, 7:38:07 PM4/7/11
to

ThosRTanner wrote:
[...]


> I expect it to not compile. It is possible for the compiler to detect
> that a nothrow function is calling a function which might throw.

Do you expect int f() { return 1/zero; } also not compile if compiler
detects that zero is 0?

regards,
alexander.

Alexander Terekhov

unread,
Apr 7, 2011, 7:35:39 PM4/7/11
to

"dietma...@yahoo.com" wrote:
[...]


> throwing any exceptions. Of course, once sections of code are
> known not to throw the compiler can also apply magic - just that
> I don't know what they are as I'm a library guy.

If code can throw (exception propagation is possible), the
problems are the following:

https://db.usenix.org/events/wiess2000/full_papers/dinechin/dinechin.pdf

"3.8 Remaining Negative Effects

Even with landing pads, exception handling still has a
cost. The space overhead of enabling exception handling
includes the code for the landing pads, exception switches,
destructor calls and catch handlers, as well as the space for
all the exception handling tables. This remains significant
in terms of memory usage, even though the performance
impact of this additional memory can be kept low by
carefully segregating hot and cold memory.

However, performance itself can remain affected by a
variety of factors:

- Additional control flow arcs between the main code call
sites and the various exception handlers and destructor
calls make the control flow graph much more complex.

- One result is to prevent some otherwise valid code
motion, when the code motion cannot be correctly
compensated for in the landing pad, or when the cost of
compensating would be too high.

- Another effect is to effectively lower the amount of
optimization that can be done on a given piece of code
in a given amount of time. Since compilers also have a
compile-time performance constraint, they may "bail
out" if optimization would take too long. This will
happen earlier in the presence of exception handling.

- Another instance of resource limitation occurs on
optimizations that copy or duplicate code, such as
inlining. These optimizations typically have a "budget",
and this budget gets exhausted much more rapidly in
the presence of exceptions, since duplicating the main
body of code generally means duplicating the
exception-handling data and code as well.

- A final problem evoked above remains unsolved: any
optimizer that performs on the code has to know about
exception handling tables and how to reorder them.
With limited engineering resources, some specific
optimizations may purposedly be disabled in the
presence of exceptions."

regards,
alexander.

restor

unread,
Apr 8, 2011, 8:07:33 AM4/8/11
to

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

Hi, While your concern might be valid in genegal, the example you
provide
is IMO not a good one. Databases have their own, better, way of
assuring
the consistent state: transactions. Transactions are immune even to
program
crashes (note that calling std::terminate is not a crash) at random
times:
the state is reverted to the previous valid one; that is, if you use
transactions well.


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

I think the approach not to declare functions as noexcept is a good
one,
and every normal programmer should be discouraged from annotating his
functions with noexcept. Functions do and should throw exceptions, and
declarations do not change it. "noexcept" functions are only required
as
very basic building blocks for providing exception safety guarantees
and
making exception handling mechanism work. The functions that need to
be
noexcept include:

* std::swap()
* std::terminate() itself
* std::uncaught_exception()
* std::atexit()
* std::set_termainate()
* operators delete and delete[]
* std::type_info members
* ideally constructors of exception classes
* ideally destructors
* ideally move constructors

We may not like it but destructors and move constructors will be
declared
as noexcept(true). For move constructors it is not a breaking change
as we
did not use to have them and compiler-generated ones will be compiler-
guaranteed
to be correct. The case is different for destructors: you may wish to
annotate
your destructor as noexcept(false) if you do want it to throw.
Apart from that it will be only STD library authors that will declare
their
functions with noexcept.


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

It is well-specified in C++ standard what should cause a compilation
error. It is only warnings that are not specified, because usually a
suspicious
language construct may be correct or may be incorrect, and compiler
cannot
tell that without wider context. E.g.:

if( var = getVal() ) ...

It might be a typical mistake of confusing == with =, or it might be
exactly
what you intended. Compiler cannot just reject the code.
This is similar with noexcept. Consider the following code:

double Sqrt( double arg ); // throws on negative arguments

double Compute( double arg ) noexcept
{
if( arg >= 0.0 )
return Sqrt( arg );
else
return 0.0;
}

Here the author can guarantee that Compute() doesn't throw, even
thought it is calling
a throwing function inside. Compiler should not stop him.

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

Note that even now, in C++03, you have the problem of not executing
destructors of automatic objects if you do not catch exceptions thrown
out of function main(); as though main was already declared with
noexcept.
In this sense noexcept's behavior is not a new concept.

Regards,
&rzej

DeMarcus

unread,
Apr 8, 2011, 8:06:47 AM4/8/11
to

On 04/08/2011 01:38 AM, Alexander Terekhov wrote:
>
>
> ThosRTanner wrote:
> [...]
>> I expect it to not compile. It is possible for the compiler to detect
>> that a nothrow function is calling a function which might throw.
>
> Do you expect int f() { return 1/zero; } also not compile if compiler
> detects that zero is 0?
>

Yes, if the function was declared

int f() nodivbyzero;

then I would definitely expect that the function is ill-formed if it
does a division by zero.

I guess Dave Abrahams must be quite disappointed. His noexcept has
turned into an optimization flag that no one understands or knows how to
use.

Alexander Terekhov

unread,
Apr 8, 2011, 4:42:55 PM4/8/11
to

DeMarcus wrote:
>
> On 04/08/2011 01:38 AM, Alexander Terekhov wrote:
> >
> >
> > ThosRTanner wrote:
> > [...]
> >> I expect it to not compile. It is possible for the compiler to detect
> >> that a nothrow function is calling a function which might throw.
> >
> > Do you expect int f() { return 1/zero; } also not compile if compiler
> > detects that zero is 0?
> >
>
> Yes, if the function was declared
>
> int f() nodivbyzero;
>
> then I would definitely expect that the function is ill-formed if it
> does a division by zero.

What about int f() nodivbyzero { int n; cin >> n; return 1/n; } then?

BTW, regarding void f() noexcept { throw 0; } I agree that it is
reasonable to expect a compiler warning. But just a warning (and which
can be turned off).

regards,
alexander.

Alexander Terekhov

unread,
Apr 8, 2011, 4:43:06 PM4/8/11
to

restor wrote:
[...]


> I think the approach not to declare functions as noexcept is a good
> one,
> and every normal programmer should be discouraged from annotating his
> functions with noexcept. Functions do and should throw exceptions, and
> declarations do not change it. "noexcept" functions are only required

Ideally, given that in C++ predecessor standard C without exceptions
functions do not throw and it is quite possible to write C++ code
without using exceptions, noexcept(true) shall be the default. For a
throwing function, the list of exceptions shall be declared with "..."
or some such indication for an open-ended list. So noexcept(false) would
just mean throw(...) exception specification. Instead of deprecating
exception specifications I'd simply fix them by making throw() mean
noexcept(true), allowing use of "...", and mandatory forbidding
unwinding on violations.

regards,
alexander.

ThosRTanner

unread,
Apr 8, 2011, 4:41:49 PM4/8/11
to

On Apr 8, 12:38 am, Alexander Terekhov <terek...@web.de> wrote:
> ThosRTanner wrote:
>
> [...]
>
> > I expect it to not compile. It is possible for the compiler to detect
> > that a nothrow function is calling a function which might throw.
>
> Do you expect int f() { return 1/zero; } also not compile if compiler
> detects that zero is 0?
>

Some compilers do, actually. However, f() isn't specifically declared
to say it doesn't divide by zero, so I could forgive them.

My personal feeling is it's at about the same level as allowing this:

int f(char const * i_wont_update_this)
{
if (some_condition) *i_wont_update_this = 0;
}

to compile, and then generating a runtime error.

restor

unread,
Apr 8, 2011, 4:43:23 PM4/8/11
to

> >> I expect it to not compile. It is possible for the compiler to detect
> >> that a nothrow function is calling a function which might throw.
>
> > Do you expect int f() { return 1/zero; } also not compile if compiler
> > detects that zero is 0?
>
> Yes, if the function was declared
>
> int f() nodivbyzero;
>
> then I would definitely expect that the function is ill-formed if it
> does a division by zero.

I do not know fully the new noexcept behaviour, but from what I
understand the following code is absolutely valid and should be able
to do something useful.

void DoSomethingUseful();

void LaunchApplication() constexpr {
throw "CallTerminate";
}

int main() {
std::set_terminate( &DoSomethingUseful );
LaunchApplication();
}

Compiler might warn me, but according to 15.4/11, "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 can hardly believe that it is an intent. Would it not be
more appropriate to add something like below to the standard.

"Implementation is allowed (but not required) to reject the code, if
it can prove that when the progam is executed it triggers the event of
stack unwinding reaching the outermost scope of the function declared
with noexcept, or function main."

Regards,
&rzej

Daniel Krügler

unread,
Apr 8, 2011, 4:41:25 PM4/8/11
to

On 2011-04-08 14:07, restor wrote:
>

[..]

> We may not like it but destructors and move constructors will be
> declared as noexcept(true). For move constructors it is not a breaking change
> as we did not use to have them and compiler-generated ones will be compiler-
> guaranteed to be correct.

This information about move-constructors and noexcept is clearly wrong
(or I misunderstand what you try to say here): C++0x will not impose any
nothrow-requirements on move-related special member functions. It is
probably recommended for everyone to have a nothrow-movable type, but
this is nothing which the language or the library enforces. The library
will ensure - as a service to programmers using it - that library
components are designed to be nothrow-movable, where possible. If such a
component, e.g. std::vector in regard to insert, depends on a
user-provided type, this is of-course depending on the implemented
behaviour of the user-provided type.

> The case is different for destructors: you may wish to
> annotate
> your destructor as noexcept(false) if you do want it to throw.
> Apart from that it will be only STD library authors that will declare
> their functions with noexcept.

... which they usually don't need to do in an active form, because the
language assigns a default nothrow-exception-specification to all
destructors, unless base classes or member types don't object actively.

HTH & Greetings from Bremen,

- Daniel Krügler

Daniel Krügler

unread,
Apr 8, 2011, 10:16:32 PM4/8/11
to
Am 08.04.2011 22:43, schrieb restor:
>
>>>> I expect it to not compile. It is possible for the compiler to detect
>>>> that a nothrow function is calling a function which might throw.
>>
>>> Do you expect int f() { return 1/zero; } also not compile if compiler
>>> detects that zero is 0?
>>
>> Yes, if the function was declared
>>
>> int f() nodivbyzero;
>>
>> then I would definitely expect that the function is ill-formed if it
>> does a division by zero.
>
> I do not know fully the new noexcept behaviour, but from what I
> understand the following code is absolutely valid and should be able
> to do something useful.
>
> void DoSomethingUseful();
>
> void LaunchApplication() constexpr {
> throw "CallTerminate";
> }

You probably meant

void LaunchApplication() noexcept {
throw "CallTerminate";
}

here, because the former function definition is ill-formed, no diagnostic
required.

> int main() {
> std::set_terminate(&DoSomethingUseful );


> LaunchApplication();
> }
>
> Compiler might warn me, but according to 15.4/11, "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 can hardly believe that it is an intent. Would it not be
> more appropriate to add something like below to the standard.
>
> "Implementation is allowed (but not required) to reject the code, if
> it can prove that when the progam is executed it triggers the event of
> stack unwinding reaching the outermost scope of the function declared
> with noexcept, or function main."

The current behaviour is intended.

HTH & Greetings from Bremen,

- Daniel Krügler


Martin B.

unread,
Apr 8, 2011, 10:15:54 PM4/8/11
to
On 08.04.2011 14:06, DeMarcus wrote:
>
> On 04/08/2011 01:38 AM, Alexander Terekhov wrote:
>>
>>
>> ThosRTanner wrote:
>> [...]
>>> I expect it to not compile. It is possible for the compiler to detect
>>> that a nothrow function is calling a function which might throw.
>>
>> Do you expect int f() { return 1/zero; } also not compile if compiler
>> detects that zero is 0?
>>
>
> Yes, if the function was declared
>
> int f() nodivbyzero;
>
> then I would definitely expect that the function is ill-formed if it
> does a division by zero.
>

I too have a wish list as long as both arms to the Compiler Santa Claus. :-)

> I guess Dave Abrahams must be quite disappointed. His noexcept has

I doubt it. From what I gleamed from the stuff I read from him, he knows
the standardization process far too well to be disappointed. :-)

> turned into an optimization flag that no one understands or knows how to
> use.
>

While it seems really disappointing that the new standard *forbids*
compilers from issuing an error, even if they can statically prove that
noexcept is violated, imho this thread has already shown where and how
it *will* be useful. (And that it is really not harder to understand
than any other nook of the language.)

cheers,
Martin

restor

unread,
Apr 9, 2011, 7:01:57 AM4/9/11
to

>> We may not like it but destructors and move constructors will be
>> declared as noexcept(true). For move constructors it is not a breaking change
>> as we did not use to have them and compiler-generated ones will be compiler-
>> guaranteed to be correct.
>
> This information about move-constructors and noexcept is clearly wrong
> (or I misunderstand what you try to say here): C++0x will not impose any
> nothrow-requirements on move-related special member functions.

You understood me well. What I said was incorrect.
Sorry for confusing everyone.


>> The case is different for destructors: you may wish to
>> annotate
>> your destructor as noexcept(false) if you do want it to throw.
>> Apart from that it will be only STD library authors that will declare
>> their functions with noexcept.
>
> ... which they usually don't need to do in an active form, because the
> language assigns a default nothrow-exception-specification to all
> destructors, unless base classes or member types don't object actively.

And it looks I was also incorrect about destructors too. I tried to
read through the latest standard draft and I found the following rule
for destructors (correct me if I am wrong).

struct POD {
std::string name_;
~POD() { // (1) implicitly noexcept(true)
name_.clear();
}
};

struct LoggedA {
POD pod_;
~LoggedA() { //(2) implicitly noexcept(true)
LOG() << pod_; // may throw
}
};

struct LoggedB {
POD pod_;
~LoggedB() noexcept(false) { //(3)
LOG() << pod_; // may throw
}
};

struct Big {
LoggedB logged_;
~Big() { // (4) IMPLICIT noexcept(false)
; // empty
}
};

That is, as in (2) if all sub-objects have noexcept(true) destructors,
our destructor is by default also a noexcept(true) one even if we
throw
in the body. However, if we have a noexcept(false) sub-object, our
destructor is by default noexcept(false).

Regards,
&rzej

Daniel Krügler

unread,
Apr 9, 2011, 3:36:38 PM4/9/11
to
Am 09.04.2011 13:01, schrieb restor:
>

[..]

>>> The case is different for destructors: you may wish to
>>> annotate
>>> your destructor as noexcept(false) if you do want it to throw.
>>> Apart from that it will be only STD library authors that will declare
>>> their functions with noexcept.
>>
>> ... which they usually don't need to do in an active form, because the
>> language assigns a default nothrow-exception-specification to all
>> destructors, unless base classes or member types don't object actively.
>
> And it looks I was also incorrect about destructors too. I tried to
> read through the latest standard draft and I found the following rule
> for destructors

Before answering let me anticipate that there is one current defect in
the core wording, because it misses to clarify *which* form of the
nothrowing exception-specification (throw() or the equivalent of
noexcept(true)) will be applied. In my reply below I ignore this detail
and assume that it will be the equivalent of noexcept(true).

(correct me if I am wrong).
>
> struct POD {
> std::string name_;
> ~POD() { // (1) implicitly noexcept(true)
> name_.clear();
> }
> };

Correct (The name POD here is a bit misleading here, because POD is not
a POD type).

During the Madrid meeting the following new library requirement has been
added:

"Every destructor in the C++ standard library shall behave as if it had
a non-throwing exception specification."

which allows this deduction from std::string.

> struct LoggedA {
> POD pod_;
> ~LoggedA() { //(2) implicitly noexcept(true)
> LOG()<< pod_; // may throw
> }
> };

Correct.

> struct LoggedB {
> POD pod_;
> ~LoggedB() noexcept(false) { //(3)
> LOG()<< pod_; // may throw
> }
> };
>
> struct Big {
> LoggedB logged_;
> ~Big() { // (4) IMPLICIT noexcept(false)
> ; // empty
> }
> };

Correct.

> That is, as in (2) if all sub-objects have noexcept(true) destructors,
> our destructor is by default also a noexcept(true) one even if we
> throw
> in the body. However, if we have a noexcept(false) sub-object, our
> destructor is by default noexcept(false).

Yes, this is the mental model behind that (ignoring details about
dynamic-exception-specifications). For reference to others I provide
some relevant normative wording:

1) 12.4 [class.dtor] p. 3:

"A declaration of a destructor that does not have an
exception-specification is implicitly considered to have the same
exception-specification as an implicit declaration (15.4)."

This explains why in (2) the compiler is requested to ignore the content
of destructor body. It is supposed to look into 15.4 instead, which
follows below. Example (3) is the only case where a destructor has a
non-implicit exception-specification.

2) 15.4 [except.spec] p. 14:

"An implicitly declared special member function (Clause 12) shall have
an exception-specification. If f is an implicitly declared [..]
destructor, [..] its implicit exception-specification specifies the
type-id T if and only if T is allowed by the exception-specification of
a function directly invoked by f's implicit definition; f shall allow
all exceptions if any function it directly invokes allows all
exceptions, and f shall allow no exceptions if every function it
directly invokes allows no exceptions."

a) The first sentence makes clear, that *all* destructors have an
exception-specification.

b) The reference to

"a function directly invoked by f's implicit definition"

ensures that the compiler is supposed to look at the
exception-specifications of the destructors of the non-static members
and base classes solely (It is an indirect consequence of 15.4 again not
to look into the destructor body of any of these).

c) There are no non-empty dynamic-exception-specifications involved
here, so the sentence about "type-id T" is irrelevant here.

d) The part

"f shall allow all exceptions if any function it directly invokes allows
all exceptions"

has the effect that (4) has to add the exception-specification
noexcept(false) because it's member LoggedB has an
exception-specification that allows all exceptions.

In all other cases (and given the new library guarantee mentioned above)
we fall into the last part:

"f shall allow no exceptions if every function it directly invokes
allows no exceptions"

Again: These functions can *only* be destructors, never functions that
are called in some body of any of these destructors.

HTH & Greetings from Bremen,

Daniel Krügler

Alexander Terekhov

unread,
Apr 9, 2011, 3:36:55 PM4/9/11
to
"Martin B." wrote:
>
> On 08.04.2011 14:06, DeMarcus wrote:
[...]

> > I guess Dave Abrahams must be quite disappointed. His noexcept has
>
> I doubt it. From what I gleamed from the stuff I read from him, he knows
> the standardization process far too well to be disappointed. :-)
>
> > turned into an optimization flag that no one understands or knows how to
> > use.
> >
>
> While it seems really disappointing that the new standard *forbids*
> compilers from issuing an error, even if they can statically prove that
> noexcept is violated, imho this thread has already shown where and how
> it *will* be useful. (And that it is really not harder to understand
> than any other nook of the language.)

To me, noexcept is definitely a step in the right direction. Sadly, it
is deficient because it does not forbid unwinding on violations: if I
want unwinding, I can always write a wrapping try {...} catch(...)
{...}, now what am I supposed to write if I do NOT want unwinding, given
that I've already wrote noexcept(true)? That's deficiency, for sure.
Another deficiency is that apart from unwinding, given that
noexcept(false) is basically throw(...) exception specification, why can
I not limit that open-ended list of exception types to, say, just one
element X: throw(X) exception specification?
regards,
alexander.

Martin B.

unread,
Apr 10, 2011, 7:49:25 PM4/10/11
to

On 08.04.2011 22:41, ThosRTanner wrote:
>
> On Apr 8, 12:38 am, Alexander Terekhov<terek...@web.de> wrote:
>> ThosRTanner wrote:
>>
>> [...]
>>
>>> I expect it to not compile. It is possible for the compiler to detect
>>> that a nothrow function is calling a function which might throw.
>>
>> Do you expect int f() { return 1/zero; } also not compile if compiler
>> detects that zero is 0?
>>
>
> Some compilers do, actually. However, f() isn't specifically declared
> to say it doesn't divide by zero, so I could forgive them.
>
> My personal feeling is it's at about the same level as allowing this:
>
> int f(char const * i_wont_update_this)
> {
> if (some_condition) *i_wont_update_this = 0;
> }
>
> to compile, and then generating a runtime error.
>

The problem though is, that while a (necessarily static) const violation can be easily and fully validated by the compiler, a noeexcept violation *cannot* (at least not easily), because the std *allows* a noexcept function to call any other function, even when not marked as such -- as opposed to const-ness which has to statically propagate all the way through.

Having the compiler reject (A):

void f() noexcept {
throw 42;
}

but then accept (B):

void g() {
throw 42;
}
void f() noexcept {
g();
}

would certainly only be marginally useful, and *requiring* the compiler to be able to statically prove noexcept violation in (B) is IMHO much too sophisticated to be standardized.

The only way to force/make compilers to statically prove noexcept violations would have been to allow noexcept function to only call other noexcept functions, and apparently they thought that this would have been the worse solution.

cheers,
Martin

Nevin :-] Liber

unread,
Apr 10, 2011, 7:49:51 PM4/10/11
to

In article <eZ6dnWRdDP0BCQTQ...@bt.com>,
Francis Glassborow <francis.g...@btinternet.com> wrote:

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

I thought the motivation was to address the problem that containers
cannot take much advantage of move constructors if those constructors
can throw. This being C++, we like general mechanisms to solve specific
problems.

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

Because it has defined semantics, it really isn't about requirements
anymore. It does not say that the body isn't allowed to throw; rather,
it says what happens when the body throws an uncaught exception.

This is the reason that much of the Madrid standards meeting was spent
removing most of the noexcepts that were added in Batavia and replaced
with "throws nothing" in the documentation.

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

Francis Glassborow

unread,
Apr 11, 2011, 4:23:34 AM4/11/11
to
On 11/04/2011 00:49, Nevin :-] Liber wrote:
> In article<eZ6dnWRdDP0BCQTQ...@bt.com>,
> Francis Glassborow<francis.g...@btinternet.com> wrote:
>
>> I believe that the motivation behind 'noexcept' was to pull the
>> functionality of throw() out of exception specifications
>
> I thought the motivation was to address the problem that containers
> cannot take much advantage of move constructors if those constructors
> can throw. This being C++, we like general mechanisms to solve specific
> problems.
>
>> 1) We can provide more detailed requirements for that case without having t=
>> o
>> add verbiage to everywhere that throw specifications are mentioned.
>
> Because it has defined semantics, it really isn't about requirements
> anymore. It does not say that the body isn't allowed to throw; rather,
> it says what happens when the body throws an uncaught exception.
>
> This is the reason that much of the Madrid standards meeting was spent
> removing most of the noexcepts that were added in Batavia and replaced
> with "throws nothing" in the documentation.
>
So I take my eye off the ball and they immediately start messing up
again :( I originally opposed throw specifications unless they could be
statically enforced and the BSI panel agreed (this is back in the early
1990s) but somehow our representatives at WG21 (I wasn't going regularly
at that time) were persuaded otherwise. Time showed that our original
position was correct. Now I retire from active attendance and they mess
up again :(

I am sure that noexcept was originally intended to be statically
enforced and it loses a great deal by not being. Though at least it
allows us to eventually get rid of throw specifications without throwing
out the baby with the bathwater.


--

DeMarcus

unread,
Apr 11, 2011, 4:24:45 AM4/11/11
to
>> I guess Dave Abrahams must be quite disappointed. His noexcept has
>
> I doubt it. From what I gleamed from the stuff I read from him, he knows
> the standardization process far too well to be disappointed. :-)
>

His original idea with noexcept was to help programmers conform to his
exception guarantees.

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

Today, noexcept has nothing to do with exception guarantees. Today
noexcept is a way to save a couple of clock cycles when doing operations
that *may* not throw. The noexcept flag does definitely not conform to
the principle of least surprise.

It feels like the committee has focused so hard to solve the technical
details so they completely lost focus on why noexcept was introduced and
how everyday programmers shall use it in practice.

Martin B.

unread,
Apr 11, 2011, 7:58:19 AM4/11/11
to

On 11.04.2011 10:24, DeMarcus wrote:
>>> I guess Dave Abrahams must be quite disappointed. His noexcept has
>>
>> I doubt it. From what I gleamed from the stuff I read from him, he knows
>> the standardization process far too well to be disappointed. :-)
>>
>
> His original idea with noexcept was to help programmers conform to his
> exception guarantees.
>
> http://www.boost.org/community/exception_safety.html
>

Ah, I know this page and it's certainly interesting.

What might be more interesting and more relevant to this discussing
though would be a history of the noexcept proposal and how it (and what)
changed until we got where we are now wrt. to the std.

> Today, noexcept has nothing to do with exception guarantees. Today
> noexcept is a way to save a couple of clock cycles when doing operations
> that *may* not throw. The noexcept flag does definitely not conform to
> the principle of least surprise.
>
> It feels like the committee has focused so hard to solve the technical
> details so they completely lost focus on why noexcept was introduced and
> how everyday programmers shall use it in practice.
>

And to me it feels some people here are focusing to hard on what
noexcept doesn't do and what they're disappointed with so they loose the
perspective of what it can do and where it will be useful. :-)

cheers,
Martin

DeMarcus

unread,
Apr 11, 2011, 7:59:03 AM4/11/11
to

I don't understand why that would be a worse solution?

Also, it can be solved with the original noexcept block

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

The noexcept block would help the compiler statically prove noexcept
violation. What's more important though, it would give the programmer a
chance to review the code, just like a programmer should review the code
after having used reinterpret_cast or const_cast.

Daniel James

unread,
Apr 11, 2011, 8:16:59 PM4/11/11
to

In article <inso9u$1ai$1...@dont-email.me>, Martin B. wrote:
> Having the compiler reject (A):
>
> void f() noexcept {
> throw 42;
> }
>
> but then accept (B):
>
> void g() {
> throw 42;
> }
> void f() noexcept {
> g();
> }
>
> would certainly only be marginally useful ...

I agree.

> ... and *requiring* the compiler to be able to statically prove


> noexcept violation in (B) is IMHO much too sophisticated to be
> standardized.

What's wrong with having the compiler reject B altogether unless and
until g() is also made "noexcept".

A rule that said "a noexcept function may not call any other function
(or operator) unless that function is also noexcept" would be a tougher
constraint for programmers to meet, but would guarantee something that
is actually useful (unlike A) and would not be too hard for compilers to
implement.

The parallels with "const" have been remarked upon upthread.

Unless "noexcept" can be checked statically it will have all the same
problems of the exception specifications that have been in the language
for years, have hardly ever been used, and are now deprecated.

BTW Why is it spelt "noexcept" rather than "nothrow"?

--
Regards,
Daniel.
[Lest there be any confusion I am NOT the Boost maintainer of the same
name]

DeMarcus

unread,
Apr 11, 2011, 8:14:41 PM4/11/11
to

On 04/08/2011 10:42 PM, Alexander Terekhov wrote:
>
>
> DeMarcus wrote:
>>
>> On 04/08/2011 01:38 AM, Alexander Terekhov wrote:
>>>
>>>
>>> ThosRTanner wrote:
>>> [...]
>>>> I expect it to not compile. It is possible for the compiler to detect
>>>> that a nothrow function is calling a function which might throw.
>>>
>>> Do you expect int f() { return 1/zero; } also not compile if compiler
>>> detects that zero is 0?
>>>
>>
>> Yes, if the function was declared
>>
>> int f() nodivbyzero;
>>
>> then I would definitely expect that the function is ill-formed if it
>> does a division by zero.
>
> What about int f() nodivbyzero { int n; cin>> n; return 1/n; } then?
>

Theoretically, if we would want to imitate some kind of noexcept, above code would fail to compile since n *can* be 0.

If we know for sure n will never be zero, we would have to write the code like this.

int f() nodivbyzero
{
int n;
cin >> n;

nodivbyzero{ return 1/n; }
}

/If/ n would be zero anyway, then std::terminate would be called just like it's proposed with current noexcept.

So what did we achieve with the nodivbyzero block in the return statement? We get the possibility to let the compiler statically check that the programmer fulfill what he/she promises. It also directly points out the vulnerable place with the nodivbyzero block, just like an interpret_cast or const_cast do.

All in all, if we apply the noexcept block

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

we have the same functionality as before /plus/ the possibility to statically check noexcept violations.

Martin B.

unread,
Apr 11, 2011, 8:22:13 PM4/11/11
to

On 11.04.2011 13:59, DeMarcus wrote:
>
> On 04/11/2011 01:49 AM, Martin B. wrote:
>>
>> On 08.04.2011 22:41, ThosRTanner wrote:
>>>
>>> On Apr 8, 12:38 am, Alexander Terekhov<terek...@web.de> wrote:
>>>> ThosRTanner wrote:
>>>>
>>>> [...]
>>>>
>>>>> I expect it to not compile. It is possible for the compiler to detect
>>>>> that a nothrow function is calling a function which might throw.
>>>>
>>>> ...

>>>>
>>>
>>>
>>> My personal feeling is it's at about the same level as allowing this:
>>>
>>> int f(char const * i_wont_update_this)
>>> {
>>> if (some_condition) *i_wont_update_this = 0;
>>> }
>>>
>>> to compile, and then generating a runtime error.
>>>
>>
>> The problem though is, that while a (necessarily static) const violation
>> can be easily and fully validated by the compiler, a noeexcept violation
>> *cannot* (at least not easily), because the std *allows* a noexcept
>> function to call any other function, even when not marked as such -- as
>> opposed to const-ness which has to statically propagate all the way
>> through.
>> ...

>>
>> The only way to force/make compilers to statically prove noexcept
>> violations would have been to allow noexcept function to only call other
>> noexcept functions, and apparently they thought that this would have
>> been the worse solution.
>>
>
> I don't understand why that would be a worse solution?
>

I too, have no clue why. Note how I wrote: "they though that this ..." - someone on the committee might know, I do not.

> Also, it can be solved with the original noexcept block
>
> http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2855.html#noexcept-block
>

Thanks for the link!

Yes it could. But they (the committee) decided otherwise. No clue why, sorry. (Maybe one hint would be that they wanted to avoid UB.)

cheers,
Martin

Daniel Krügler

unread,
Apr 12, 2011, 8:21:04 AM4/12/11
to

On 2011-04-12 02:16, Daniel James wrote:
>
> BTW Why is it spelt "noexcept" rather than "nothrow"?

Because std::nothrow is an already existing library component.

HTH & Greetings from Bremen,

Daniel Krügler


--

DeMarcus

unread,
Apr 12, 2011, 10:37:28 PM4/12/11
to
On 04/11/2011 01:58 PM, Martin B. wrote:
>
> On 11.04.2011 10:24, DeMarcus wrote:
>>>> I guess Dave Abrahams must be quite disappointed. His noexcept has
>>>
>>> I doubt it. From what I gleamed from the stuff I read from him, he knows
>>> the standardization process far too well to be disappointed. :-)
>>>
>>
>> His original idea with noexcept was to help programmers conform to his
>> exception guarantees.
>>
>> http://www.boost.org/community/exception_safety.html
>>
>
> Ah, I know this page and it's certainly interesting.
>

It's not just interesting, it's one of the most important findings the
last decades when it comes to create solid applications.

> What might be more interesting and more relevant to this discussing
> though would be a history of the noexcept proposal and how it (and what)
> changed until we got where we are now wrt. to the std.
>

That's what's frightening me; the total drift from the original issue.
So in a way you are right; how could a code-robustness feature become a
save-clockcycles feature?

>> Today, noexcept has nothing to do with exception guarantees. Today
>> noexcept is a way to save a couple of clock cycles when doing operations
>> that *may* not throw. The noexcept flag does definitely not conform to
>> the principle of least surprise.
>>
>> It feels like the committee has focused so hard to solve the technical
>> details so they completely lost focus on why noexcept was introduced and
>> how everyday programmers shall use it in practice.
>>
>
> And to me it feels some people here are focusing to hard on what
> noexcept doesn't do and what they're disappointed with so they loose the
> perspective of what it can do and where it will be useful. :-)
>

I'm just pragmatic Martin. I know that when noexcept is shipped in its
current form it will be banned by technical leads all over the world
just like exception specifications were. Look at it, what differs
between the two anyway? We will have noexcept in the standard library,
yes, but nowhere else since it's not worth the risk.

People in this newsgroup may be smart enough to see all possible ways a
function can throw, but that doesn't hold for the majority of the
programmers. I challenge you to, during a month period, count all the
times your compiler complains about a *const* violation. Then take that
number and multiply it with your average time it takes to fix a bug.
Multiply that with your hour rate and you will have your direct monthly
cost of noexcept. Your indirect cost is debatable, here's one example.

http://www.superwebdeveloper.com/2009/11/25/the-incredible-rate-of-diminishing-returns-of-fixing-software-bugs/


The least the committee can do is to rename the keyword 'noexcept' to
'optimized' or something to prevent confusion.

However, preferably noexcept should be postponed until all issues are
resolved. See for instance this important aspect:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3248.pdf


--

SG

unread,
Apr 12, 2011, 10:38:12 PM4/12/11
to
On 12 Apr., 02:16, Daniel James wrote:

> In article Martin B. wrote:
> > Having the compiler reject (A):
>
> > void f() noexcept {
> > throw 42;
> > }
>
> > but then accept (B):
>
> > void g() {
> > throw 42;
> > }
> > void f() noexcept {
> > g();
> > }
>
> > would certainly only be marginally useful ...
>
> I agree.
>
> > ... and *requiring* the compiler to be able to statically prove
> > noexcept violation in (B) is IMHO much too sophisticated to be
> > standardized.
>
> What's wrong with having the compiler reject B altogether unless and
> until g() is also made "noexcept".

In some corner cases one would like to be able to invoke some function
knowing that it never throws but has been declared without noexcept.
So, we would need an escape hatch for noexcept just like const_cast is
an escape hatch for const. Given such an escape hatch, I don't see a
reason not to enforce static checking. Maybe I'm missing something. If
so, please comment.

Cheers!
SG


--

DeMarcus

unread,
Apr 12, 2011, 10:40:59 PM4/12/11
to
>> Also, it can be solved with the original noexcept block
>>
>> http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2855.html#noexcept-block
>>
>>
>
> Thanks for the link!
>
> Yes it could. But they (the committee) decided otherwise. No clue why,
> sorry. (Maybe one hint would be that they wanted to avoid UB.)
>

They don't need to have UB for the noexcept block, they could have
std::terminate as they want in the current draft. Actually we can have
all the things they want /plus/ static check if we use the noexcept block.

I would really like to read somewhere why static checking is bad.

I read an interview with Bjarne Stroustrup...

http://www.codeguru.com/cpp/misc/print.php/c18357/An-Interview-with-C-Creator-Bjarne-Stroustrup.htm

...where he says:
"No language has succeeded in providing a system of static checking that
is not crippling for large systems, inefficient, or easily bypassed."

So what about const?

Why is static checking inefficient? Why is it crippling large systems?

Regarding noexcept in the current draft, its static checking is worse
than easily bypassed since it's bypassed by default. When bypassing with
const_cast we at least know we are doing something bad.

As a matter of fact, I don't understand his comment at all. I thought
that in C++ /everything/ is statically checked except for virtual
functions, dynamic_cast and exception specifications, where the latter
will be deprecated.


--

Öö Tiib

unread,
Apr 13, 2011, 3:55:42 AM4/13/11
to
On Apr 12, 3:16 am, Daniel James <dan...@me.invalid> wrote:
>
> What's wrong with having the compiler reject B altogether unless and
> until g() is also made "noexcept".
>
> A rule that said "a noexcept function may not call any other function
> (or operator) unless that function is also noexcept" would be a tougher
> constraint for programmers to meet, but would guarantee something that
> is actually useful (unlike A) and would not be too hard for compilers to
> implement.

Try again. That "rule" will reject following code:

void x()
{
throw 42;
}

void y() noexcept
{
try
{
x();
}
catch( ... )
{ }
}


--

Alexander Terekhov

unread,
Apr 13, 2011, 4:01:33 AM4/13/11
to
SG wrote:
[...]

> reason not to enforce static checking. Maybe I'm missing something. If
> so, please comment.

One reason not to enforce static checking is not to repeat the Java's
mistake.

See
http://www.mindview.net/Etc/Discussions/CheckedExceptions

Hth.

regards,
alexander.

Francis Glassborow

unread,
Apr 13, 2011, 5:05:06 PM4/13/11
to

On 13/04/2011 08:55, 嘱 Tiib wrote:
> On Apr 12, 3:16 am, Daniel James<dan...@me.invalid> wrote:
>>
>> What's wrong with having the compiler reject B altogether unless and
>> until g() is also made "noexcept".
>>
>> A rule that said "a noexcept function may not call any other function
>> (or operator) unless that function is also noexcept" would be a tougher
>> constraint for programmers to meet, but would guarantee something that
>> is actually useful (unlike A) and would not be too hard for compilers to
>> implement.
>
> Try again. That "rule" will reject following code:
>
> void x()
> {
> throw 42;
> }
>
> void y() noexcept
> {
> try
> {
> x();
> }
> catch( ... )
> { }
> }
>
>

It is trivial to amend the 'rule' to cover this. noexcept does not say
that there will be no exceptions below this level, just that there will
be none propagated by the function.

Francis Glassborow

unread,
Apr 13, 2011, 5:04:44 PM4/13/11
to

On 13/04/2011 09:01, Alexander Terekhov wrote:
> SG wrote:
> [...]
>> reason not to enforce static checking. Maybe I'm missing something. If
>> so, please comment.
>
> One reason not to enforce static checking is not to repeat the Java's
> mistake.
>
> See
> http://www.mindview.net/Etc/Discussions/CheckedExceptions
>
> Hth.
>
> regards,
> alexander.
>
>

I completely disagree. That is a strong argument for not having
exception specifications but, IMO, it is a very weak one (like none at
all) for noexcept. To make it work well we do need the noexcept block,
but given that it should be possible to statically check code. Templates
do cause some problems but it not beyond the ability to deal with.

I think that WG21 have managed to fall into exactly the same trap with
noexcept that they did with exception specifications. As I no longer
attend meetings (what could I possibly have to contribute at my age, 69
in June before you ask) I missed the emasculation of noexcept. I am
saddened that my NB seems to have missed it as well.

Francis

SG

unread,
Apr 14, 2011, 9:47:24 AM4/14/11
to

On 13 Apr., 10:01, Alexander Terekhov wrote:
> SG wrote:
>
> [...]
>
> > reason not to enforce static checking. Maybe I'm missing something. If
> > so, please comment.
>
> One reason not to enforce static checking is not to repeat the Java's
> mistake.
>
> See http://www.mindview.net/Etc/Discussions/CheckedExceptions

Do the same arguments apply to the noexcept(bool) exception
specification? I don't think so. noexcept is only about the question
whether a function may throw or promises not to throw and not about
the exception object types.

But I actually don't like the proposed escape hatch "noexcept-
block" (see N2855). It would force us to create a new block. Variables
defined in that block will quickly cease to exist if you make these
blocks small. But small noexcept-blocks are desirable if one wants to
utilize the static checking and only disable it very locally.

Brainstorming: What about an optional static checking (QoI) where only
warnings are produced and programs not rejected? Then, we would only
need an escape hatch to turn off the warning. This could be done via
attributes:

double sqrt(double); // throws exception for negative numbers

void f(double x) noexcept {
if (x > 0) {
x = sqrt[[assumenoexcept]](x);
}
}

I think, this could be added to a later (post C++11) revision without
effects on backwards compatibility. Opinions?

Cheers!
SG

restor

unread,
Apr 14, 2011, 8:34:07 PM4/14/11
to

> Brainstorming: What about an optional static checking (QoI) where only
> warnings are produced and programs not rejected? Then, we would only
> need an escape hatch to turn off the warning. This could be done via
> attributes:
>
> double sqrt(double); // throws exception for negative numbers
>
> void f(double x) noexcept {
> if (x > 0) {
> x = sqrt[[assumenoexcept]](x);
> }
> }
>
> I think, this could be added to a later (post C++11) revision without
> effects on backwards compatibility. Opinions?

Compilers will be already allowed to do that in C++11. It will
definitely
be helpful. However, according to my understanding, when and what
warnings
are generated is not the scope of ISO standard for a programming
language.
Warnings in compilers are issued for programs that are valid programs
(and
there only exists a suspicion that it might have something wrong) and
the
job of the standard is to tell valid programs from invalid programs.

Regards,
&rzej

DeMarcus

unread,
Apr 14, 2011, 8:33:30 PM4/14/11
to

On 2011-04-13 10:01, Alexander Terekhov wrote:
> SG wrote:
> [...]
>> reason not to enforce static checking. Maybe I'm missing something. If
>> so, please comment.
>
> One reason not to enforce static checking is not to repeat the Java's
> mistake.
>
> See
> http://www.mindview.net/Etc/Discussions/CheckedExceptions
>

That paper talks about /throwing/ exceptions, not about /not/ throwing an exception. It seems that the paper was written before noexcept was proposed to C++0x. Eckel talks about the problem when code starts to swallow exceptions. I agree that mindlessly swallowing exceptions is bad, but we don't need to swallow exceptions with noexcept.

As a matter of fact, we don't need to use noexcept at all, but when we do we must ensure our design is correct. We use noexcept to provide Dave Abrahams' strong exception guarantee. If we are not interested in providing that we simply skip putting noexcept to our function.

A function is not noexcept just because it doesn't throw. One should consider the semantics of the function and ask whether this a function that must never fail. Take for instance a function that returns -1 on failure. It may not throw, but it's not a noexcept function.

SG

unread,
Apr 15, 2011, 5:07:35 PM4/15/11
to
On 15 Apr., 02:34, restor wrote:

> SG Wrote:
> > Brainstorming: What about an optional static checking (QoI) where only
> > warnings are produced and programs not rejected? Then, we would only
> > need an escape hatch to turn off the warning. This could be done via
> > attributes:
>
> > double sqrt(double); // throws exception for negative numbers
>
> > void f(double x) noexcept {
> > if (x > 0) {
> > x = sqrt[[assumenoexcept]](x);
> > }
> > }
>
> > I think, this could be added to a later (post C++11) revision without
> > effects on backwards compatibility. Opinions?
>
> Compilers will be already allowed to do that in C++11.
> It will definitely be helpful. However, according to my understanding,
> when and what warnings are generated is not the scope of ISO standard
> for a programming language.

Of course. But in case compiler vendors choose to add these kinds of
warnings, it would be nice to have a standard way of disabling them in
particular situations. Attributes was the first thing that came to my
mind.

Cheers!
SG

Alexander Terekhov

unread,
Apr 17, 2011, 3:47:06 AM4/17/11
to

DeMarcus wrote:
[...]


> a function that must never fail. Take for instance a function that
> returns -1 on failure. It may not throw, but it's not a noexcept
> function.

A function that is not supposed to throw is a noexcept function.

For example, free() is a noexcept function, and apart from thread
cancellation, in a single thread program without
pthread_cancel(pthread_self()) (i.e. compilation without -pthread or
some such), fclose() is also a noexcept function. Note that fclose() may
fail.

regards,
alexander.

restor

unread,
Apr 18, 2011, 10:03:20 AM4/18/11
to

> > a function that must never fail. Take for instance a function that
> > returns -1 on failure. It may not throw, but it's not a noexcept
> > function.
>
> A function that is not supposed to throw is a noexcept function.

While this is a valid view to be had, especially that name 'noexcept'
suggests it, note that it is not an obvious point of view, and some
people, myself included, would not agree. What do you gain from
annotating your function with noexcept? Compiler, even for C++03, can
already check (i.e. if the implementers choose to implement this
feature) if your function can throw and use this knowledge to check
other functions if they throw, or to optimize the program. No
additional keyword is needed. The reason the C++ committee introduced
the keyword was to be able to detect at compile-time that a certain
operation may throw or not, and based on this information implement
functions like move assignment in one way or the other. If you do not
want some meta-programs to choose different implementations based on
your noexcept annotations, then you do not need to use noexcept at
all.

One other usage of noexcept that I can think of is that you would like
the compiler to tell you if your function throws or not. You will not
be able to do that in C++11, but let's imagine a copiler with
statically checked noexcept. But it is still non-convincing, how do
you use this information?


> For example, free() is a noexcept function, and apart from thread
> cancellation, in a single thread program without
> pthread_cancel(pthread_self()) (i.e. compilation without -pthread or
> some such), fclose() is also a noexcept function. Note that fclose() may
> fail.

free() is a good candidate for a noexcept function because it is used
in providing a strong exception safety guarantee -- not only because
it is "not supposed to throw". function vector::front is also "not
supposed to throw" but it is not noexcept because it is not used in
providing a strong exception safety guarantee. fclose(), is a function
that does not (except as you noted above) throw exceptions. But does
it need to be annotated with noexcept? Who will benefit from this?

Regards,
&rzej

DeMarcus

unread,
Apr 18, 2011, 7:49:41 PM4/18/11
to

On 2011-04-17 09:47, Alexander Terekhov wrote:
>
>
> DeMarcus wrote:
> [...]
>> a function that must never fail. Take for instance a function that
>> returns -1 on failure. It may not throw, but it's not a noexcept
>> function.
>
> A function that is not supposed to throw is a noexcept function.
>

It depends what you mean with 'supposed'. If you in your semantics contract want to promise the users of the function that it never fails you should declare it noexcept. Just declaring a function noexcept because it doesn't throw won't help anyone, especially if you later on decides that the function should be able to fail.

> For example, free() is a noexcept function, and apart from thread
> cancellation, in a single thread program without
> pthread_cancel(pthread_self()) (i.e. compilation without -pthread or
> some such), fclose() is also a noexcept function. Note that fclose() may
> fail.
>

This one with fclose() is tricker. Especially since many use it with RAII in the destructor. But if you think of it, if it could cause inconsistency to the system if a file failed to close (e.g. when you're saving important data) then you would probably be careful promising the users of the RAII object that it will never fail or cause inconsistency.

If you ask me, I would never let fclose() be noexcept. Instead I would force the users to embrace it with try/catch(...) just to clarify that fclose() is an old function using the return value for failure.

MyRAIIClass::~MyRAIIClass() noexcept
{
try
{
int result = fclose( handle_ );
assert( result == 0 &&
"Call the customer and blame the "
"operating system. ;)" );
}
catch(...)
{
assert( false && "Why is it throwing?" );

Mathias Gaunard

unread,
Apr 19, 2011, 4:40:12 PM4/19/11
to

On 18 avr, 16:03, restor <akrze...@gmail.com> wrote:

> While this is a valid view to be had, especially that name 'noexcept'
> suggests it, note that it is not an obvious point of view, and some
> people, myself included, would not agree. What do you gain from
> annotating your function with noexcept? Compiler, even for C++03, can
> already check (i.e. if the implementers choose to implement this
> feature) if your function can throw and use this knowledge to check
> other functions if they throw, or to optimize the program.

They can only do that when the body of the function is available.

noexcept is really useful when you're declaring functions that are
compiled in a separate translation unit.

Alexander Terekhov

unread,
Apr 19, 2011, 4:40:08 PM4/19/11
to

DeMarcus wrote:
>
> On 2011-04-17 09:47, Alexander Terekhov wrote:
>>
>>
>> DeMarcus wrote:
>> [...]
>>> a function that must never fail. Take for instance a function that
>>> returns -1 on failure. It may not throw, but it's not a noexcept
>>> function.
>>
>> A function that is not supposed to throw is a noexcept function.
>>
>
> It depends what you mean with 'supposed'. If you in your semantics
> contract want to promise the users of the function that it never
> fails you should declare it noexcept. Just declaring a function

I mean

void noexcept_function() noexcept;

int main {
try {
noexcept_function();
}
catch(...) {
throw "impossible!";
}
}

> noexcept because it doesn't throw won't help anyone, especially if
> you later on decides that the function should be able to fail.

void noexcept_function(bool & failed) noexcept { failed = true; }
is a noexcept function.

>
>> For example, free() is a noexcept function, and apart from thread
>> cancellation, in a single thread program without
>> pthread_cancel(pthread_self()) (i.e. compilation without -pthread
>> or some such), fclose() is also a noexcept function. Note that
>> fclose() may fail.
>>
>
> This one with fclose() is tricker. Especially since many use it
> with RAII in the destructor. But if you think of it, if it could
> cause inconsistency to the system if a file failed to close (e.g.
> when you're saving important data) then you would probably be
> careful promising the users of the RAII object that it will never
> fail or cause inconsistency.
>
> If you ask me, I would never let fclose() be noexcept. Instead I
> would force the users to embrace it with try/catch(...) just to
> clarify that fclose() is an old function using the return value
> for failure.
>
> MyRAIIClass::~MyRAIIClass() noexcept
> {
> try
> {
> int result = fclose( handle_ );
> assert( result == 0 &&
> "Call the customer and blame the "
> "operating system. ;)" );

Rather:

deal_with_fclose_failure(result);

> }
> catch(...)
> {
> assert( false && "Why is it throwing?" );
> }
> }

I've been telling all along that thread cancel shall be disabled
by exception specifications not allowing thread cancel exception:

void noexcept_function() noexcept {
pthread_cancel(pthread_self());
pthread_testcancel(); // won't throw due to noexcept above
try {
pthread_testcancel(); // will throw now due to catch below
}
catch(thread_cancel_e) {
// swallow cancel exception
}
}

regards,
alexander.

DeMarcus

unread,
Apr 20, 2011, 3:27:39 PM4/20/11
to

On 2011-04-19 22:40, Alexander Terekhov wrote:
>
>
> DeMarcus wrote:
>>
>> On 2011-04-17 09:47, Alexander Terekhov wrote:
>>>
>>>
>>> DeMarcus wrote:
>>> [...]
>>>> a function that must never fail. Take for instance a function that
>>>> returns -1 on failure. It may not throw, but it's not a noexcept
>>>> function.
>>>
>>> A function that is not supposed to throw is a noexcept function.
>>>
>>
>> It depends what you mean with 'supposed'. If you in your semantics
>> contract want to promise the users of the function that it never
>> fails you should declare it noexcept. Just declaring a function
>
> I mean
>
> void noexcept_function() noexcept;
>
> int main {
> try {
> noexcept_function();
> }
> catch(...) {
> throw "impossible!";
> }
> }
>
>> noexcept because it doesn't throw won't help anyone, especially if
>> you later on decides that the function should be able to fail.
>
> void noexcept_function(bool& failed) noexcept { failed = true; }
> is a noexcept function.
>

That's where we disagree (and I also disagree with the current draft).
To me, the function declaration is the contract with the users of the
function. To me, a thrown exception is a failure. If you put noexcept to
a function I assume this function won't fail. Then you just sneak
through via an input argument telling it failed anyway.

If the only reason to put noexcept at a function is to save a couple of
clock cycles then it's better they rename it 'optimized' to avoid confusion.

This is more clear:

void optimized_function(bool& failed) optimized { failed = true; }

0 new messages