The basic problem I have with this is that it requires that everybody play on the same team. Either everyone examines every function for `noexcept`, or what you're doing doesn't work very well.
Right now, `noexcept` matters primarily for indicating a local construct of your program. A move constructor is `noexcept` because it doesn't do anything that might throw exceptions. If it happens to call some subsidiary functions to copy pointers or whatever, those functions don't need to be explicitly marked `noexcept`.
You put exception specifications on things where you have some reasonable expectation that someone is going to, at compile-time, do something different based on that. That's not everywhere; it's not a part of most functions.
You're trying to promote a world where every function needs to consider whether it ought to be `noexcept`. And that's just not a reasonable world. Especially if whether you're `noexcept` or not is conditioned based on the exception specification of user-provided code.
Is `std::sort` `noexcept`? Well, that would depend on whether the comparison function is `noexcept`. Do we really want every kind of algorithm to have to write some complex exception specification?
I believe, it would make little sense to standardize something like `noexcept(strong)` without something like `noexcept(auto)`, because the two specification serve different purposes, but they would work together very well.
On Friday, May 11, 2018 at 8:41:20 PM UTC+2, Nicol Bolas wrote:The basic problem I have with this is that it requires that everybody play on the same team. Either everyone examines every function for `noexcept`, or what you're doing doesn't work very well.
Yes, this is true.
But look at pair, optional, tuple, variant, array...
They are all conditionally `noexcept`.
The basic problem I have with this is that it requires that everybody play on the same team. Either everyone examines every function for `noexcept`, or what you're doing doesn't work very well.
Right now, `noexcept` matters primarily for indicating a local construct of your program. A move constructor is `noexcept` because it doesn't do anything that might throw exceptions. If it happens to call some subsidiary functions to copy pointers or whatever, those functions don't need to be explicitly marked `noexcept`.
You put exception specifications on things where you have some reasonable expectation that someone is going to, at compile-time, do something different based on that. That's not everywhere; it's not a part of most functions.
You're trying to promote a world where every function needs to consider whether it ought to be `noexcept`. And that's just not a reasonable world. Especially if whether you're `noexcept` or not is conditioned based on the exception specification of user-provided code.
Is `std::sort` `noexcept`? Well, that would depend on whether the comparison function is `noexcept`. Do we really want every kind of algorithm to have to write some complex exception specification?
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/35f89aa3-02e6-4306-a120-18cd3ebc5ddf%40isocpp.org.
@Nicol:
> Such forwarding is necessary only because those operations are ones which care very much about throwing exceptions: default initialization, copy/move operations, swapping, etc. There are very specific issues surrounding very specific operations. The optimizations you can do when you know a copy or move constructor won't throw are different from if you don't know that.
And we do an error while writing those wrapper, the compiler wont complain.
I'm not talking about possible optimizations, I'm talking about code-correctness.
The constructor of `unique-ptr` for example is `noexcept`.
Not because the underlying type might be `noexcept`, and not because someone said "just make it noexcept because I like it to behave similar to a pointer", but because we need that guarantee to write leak-safe code.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/caccaf01-b689-4214-8bc6-efe55962daf2%40isocpp.org.
The constructor of `unique-ptr` for example is `noexcept`.
Not because the underlying type might be `noexcept`, and not because someone said "just make it noexcept because I like it to behave similar to a pointer", but because we need that guarantee to write leak-safe code.
No, you don't. Your code will be leak-safe because the constructor doesn't throw, not because it is declared `noexcept`. The latter is simply one expression of the former; it is not the only one, and it should not be considered to be the only one.
Basically, I contest your entire premise that any function which is not declared `noexcept` must be expected to throw. That's simply not how C++ code is written.
The constructor of `unique-ptr` for example is `noexcept`.
Not because the underlying type might be `noexcept`, and not because someone said "just make it noexcept because I like it to behave similar to a pointer", but because we need that guarantee to write leak-safe code.
No, you don't. Your code will be leak-safe because the constructor doesn't throw, not because it is declared `noexcept`. The latter is simply one expression of the former; it is not the only one, and it should not be considered to be the only one.
Basically, I contest your entire premise that any function which is not declared `noexcept` must be expected to throw. That's simply not how C++ code is written.
Well, we clearly have completely different views for what noexcept can be used, and how we use it.
I researched the topic a little bit, as far as I can see it is recommended practice to mark functions that we do not ever want to fail with `noexcept`, and the standard library seems to do so too (see my example with `unique_ptr`, or all the functions I've listed for containers, but no only those).
Do you mind to share some resource on the topic, since you claimed that my premise is wrong (every function not marked as noexcept should be considered as a function that could throw, with minor exceptions like C functions, functions marked with throw(), operations on fundamental types and so on).
And even if "noexcept` was not created to promote code-correctness", it does not mean that it cannot be used to promote it.
Templates where also not created to do compile-time computations...
From: Nicol Bolas Sent: Thursday, May 17, 2018 9:23 PM To: ISO C++ Standard - Future Proposals Reply To: std-pr...@isocpp.org Subject: Re: [std-proposals] noexcept-correctenss |
The main reason for std functions that don't throw, but don't say noexcept, is that we allow implementations to throw on precondition violations.Otherwise, most nonthrowing functions would be marked noexcept. Or conditionally noexcept
noexcept
is akin to that of const
:
it helps me better grok what may or may not happen. Therefore, it is
worthwhile spending some time thinking about whether or not you know if
the function will throw. For reminder, any kind of dynamic memory
allocation may throw. [...] now on to the possible optimizations. [...]"noexcept
really is intended to convey is that the function never fails; not that it never throws! [...] This is part of a more general observation, that what we are
interested in is really failure safety in program components rather than
exception safety. No matter if you use exceptions, error return values, errno
or whatever else, the reasoning about basic (no leak, invariant
preserved), strong (commit or rollback) and never-fail guarantee should
still hold."3) The last point, "More eager termiation" is particularly interesting, because with what I'm proposing we would be able to reduce those runtime errors.
4) From a comment (I swear it's not mine) "IMO using noexcept is like using const [...] Just like we don’t say we should not use const because libraries may
‘mutable’ themselves out of the const contract, it does equally not seem
like a good idea to promote such a thing for what I would like to call
noexcept correctness."
The consensus, again, seems to be that if a function cannot and should not fail, then it should be marked as noexcept.
https://google.github.io/styleguide/cppguide.html
1) "You may use noexcept
when it is useful for
performance if it accurately reflects the intended semantics
of your function, i.e. that if an exception is somehow thrown
from within the function body then it represents a fatal error."
2) "instead of writing a complicated noexcept
clause
that depends on whether a hash function can throw, for example,
simply document that your component doesn’t support hash
functions throwing and make it unconditionally
noexcept
."
The guideline puts a lot of focus on performance, and that writing a correct noexcept specifier is hard (`noexcept(auto)` would therefore help), and thus use comments (hopefully some `static_assert` too).