Discussion:
[std-proposals] P0709 Heap exhaustion and try_... for standard library.
m***@gmail.com
2018-10-17 19:16:02 UTC
Permalink
In P0709, Herb Sutter proposes a zero-overhead deterministic variation of
the exception mechanism by throwing a value of a size equivalent to two
pointers.

I generally like the proposal a lot. I am doing HPC programming and
micro-controller programming and do see a lot of benefit in squelching
objections to the use of exceptions.
However, when it comes to the treatment of heap exhaustion and, more
importantly, the impact of it on the standard library, I am finding the
proposal to be disturbing.
- For each standard function for which allocation is the only
reportable error, make the function noexcept. (We expect this to result in
making a large majority of functions in the standard library noexcept,
including default and user-replaced ::operator new.)
- For code that wants to handle heap allocation failures, provide
explicit “try to allocate” functions including the existing new(nothrow)
However this approach is disturbing. It is essentially saying to go back
to an equivalent of testing an error code on return of every single call.
Also because it goes against the ideas of writing a single generic routine
for an algorithm because it seems to imply that every time I want to write
an algorithm that involves a standard library function that does a memory
allocation, I should write both a regular version and a try_*** version.
So Herb wants that the vector<T> push_back should be noexcept while the
try_push_back can throw.
Though, I can see the use for having a try_*** in places, I wonder why he
does not suggest to let the allocator used make the decision? Something
void push_back (const value_type& val) throws( can_throw_v<Alloc> ) ;
In my HPC work, I write library in which users can supply a memory buffer
that my code can use. If I run out of memory, it is out of the question
that the code would crash. Instead it should be reported to the user that
she needs to provide a bigger buffer. I can do that by using an allocator
that throws an exception. Using a solution like I suggest above would allow
to still have noexcept if the user is fine with terminate being called and
still allow to handle cases like mine gracefully in a way that I can report
to the caller as they are expecting. If the standard library always calls
terminate on failure of allocation, then I'll have to resort to not using
the standard library, but using a modified clone of it. This would be
ironic, as one of the motivations of his proposal in the first place is
that people are not using the standard library.
--
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cc411e93-53a3-4b24-8e02-68fda610c15e%40isocpp.org.
Bryce Adelstein Lelbach aka wash
2018-10-19 03:15:31 UTC
Permalink
It sounds like what you are suggesting is that instead of making library
functions that can throw unconditionally noexcept, we:

* Make them conditionally noexcept if any user defined allocators used can
throw, and
* Make std::allocator and operator new (aka the defaults) noexcept.

The result is the same in the default case; out of memory is fatal. But if
you use a customize allocator that can throw, you get the current semantics.

This sounds reasonable to me.

Have you spoke to Herb?
Post by m***@gmail.com
In P0709, Herb Sutter proposes a zero-overhead deterministic variation of
the exception mechanism by throwing a value of a size equivalent to two
pointers.
I generally like the proposal a lot. I am doing HPC programming and
micro-controller programming and do see a lot of benefit in squelching
objections to the use of exceptions.
However, when it comes to the treatment of heap exhaustion and, more
importantly, the impact of it on the standard library, I am finding the
proposal to be disturbing.
- For each standard function for which allocation is the only
reportable error, make the function noexcept. (We expect this to result in
making a large majority of functions in the standard library noexcept,
including default and user-replaced ::operator new.)
- For code that wants to handle heap allocation failures, provide
explicit “try to allocate” functions including the existing new(nothrow)
However this approach is disturbing. It is essentially saying to go back
to an equivalent of testing an error code on return of every single call.
Also because it goes against the ideas of writing a single generic routine
for an algorithm because it seems to imply that every time I want to write
an algorithm that involves a standard library function that does a memory
allocation, I should write both a regular version and a try_*** version.
So Herb wants that the vector<T> push_back should be noexcept while the
try_push_back can throw.
Though, I can see the use for having a try_*** in places, I wonder why he
does not suggest to let the allocator used make the decision? Something
void push_back (const value_type& val) throws( can_throw_v<Alloc> ) ;
In my HPC work, I write library in which users can supply a memory buffer
that my code can use. If I run out of memory, it is out of the question
that the code would crash. Instead it should be reported to the user that
she needs to provide a bigger buffer. I can do that by using an allocator
that throws an exception. Using a solution like I suggest above would allow
to still have noexcept if the user is fine with terminate being called and
still allow to handle cases like mine gracefully in a way that I can report
to the caller as they are expecting. If the standard library always calls
terminate on failure of allocation, then I'll have to resort to not using
the standard library, but using a modified clone of it. This would be
ironic, as one of the motivations of his proposal in the first place is
that people are not using the standard library.
--
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
To view this discussion on the web visit
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cc411e93-53a3-4b24-8e02-68fda610c15e%40isocpp.org
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cc411e93-53a3-4b24-8e02-68fda610c15e%40isocpp.org?utm_medium=email&utm_source=footer>
.
--
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAP3wax-C-dpaf5PutO0mv2_aUObrR136c-O7N9%3DgpKCH7o8a3Q%40mail.gmail.com.
m***@gmail.com
2018-10-19 04:18:25 UTC
Permalink
No, I have not spoken to Herb. I was looking for a way to send him a
feedback on his blog or somewhere else related to that proposal. The
closest I found is this group.

And you are right, that is what I am proposing. I think it keeps the
original goal intact but adds a (imo useful) customization point.
There could be a std::throwing_allocator too, if that seems to be useful to
many people.Or at least, given the idea of the polymorphic_allocator, since
C++17, a version of it that throws would be a good thing as well.

On Thursday, October 18, 2018 at 9:15:45 PM UTC-6, Bryce Adelstein Lelbach
Post by Bryce Adelstein Lelbach aka wash
It sounds like what you are suggesting is that instead of making library
* Make them conditionally noexcept if any user defined allocators used can
throw, and
* Make std::allocator and operator new (aka the defaults) noexcept.
The result is the same in the default case; out of memory is fatal. But if
you use a customize allocator that can throw, you get the current semantics.
This sounds reasonable to me.
Have you spoke to Herb?
Post by m***@gmail.com
In P0709, Herb Sutter proposes a zero-overhead deterministic variation of
the exception mechanism by throwing a value of a size equivalent to two
pointers.
I generally like the proposal a lot. I am doing HPC programming and
micro-controller programming and do see a lot of benefit in squelching
objections to the use of exceptions.
However, when it comes to the treatment of heap exhaustion and, more
importantly, the impact of it on the standard library, I am finding the
proposal to be disturbing.
- For each standard function for which allocation is the only
reportable error, make the function noexcept. (We expect this to result in
making a large majority of functions in the standard library noexcept,
including default and user-replaced ::operator new.)
- For code that wants to handle heap allocation failures, provide
explicit “try to allocate” functions including the existing new(nothrow)
However this approach is disturbing. It is essentially saying to go back
to an equivalent of testing an error code on return of every single call.
Also because it goes against the ideas of writing a single generic routine
for an algorithm because it seems to imply that every time I want to write
an algorithm that involves a standard library function that does a memory
allocation, I should write both a regular version and a try_*** version.
So Herb wants that the vector<T> push_back should be noexcept while the
try_push_back can throw.
Though, I can see the use for having a try_*** in places, I wonder why he
does not suggest to let the allocator used make the decision? Something
void push_back (const value_type& val) throws( can_throw_v<Alloc> ) ;
In my HPC work, I write library in which users can supply a memory buffer
that my code can use. If I run out of memory, it is out of the question
that the code would crash. Instead it should be reported to the user that
she needs to provide a bigger buffer. I can do that by using an allocator
that throws an exception. Using a solution like I suggest above would allow
to still have noexcept if the user is fine with terminate being called and
still allow to handle cases like mine gracefully in a way that I can report
to the caller as they are expecting. If the standard library always calls
terminate on failure of allocation, then I'll have to resort to not using
the standard library, but using a modified clone of it. This would be
ironic, as one of the motivations of his proposal in the first place is
that people are not using the standard library.
--
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
To view this discussion on the web visit
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cc411e93-53a3-4b24-8e02-68fda610c15e%40isocpp.org
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cc411e93-53a3-4b24-8e02-68fda610c15e%40isocpp.org?utm_medium=email&utm_source=footer>
.
--
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b701aa54-f4b6-4d9a-8980-db398aa299e4%40isocpp.org.
Ben Craig
2018-10-19 17:36:18 UTC
Permalink
"No, I have not spoken to Herb. I was looking for a way to send him a
feedback on his blog or somewhere else related to that proposal."
Almost all papers include an email address that can be used to provide
feedback. It's a paper "bug" when there is no email address included.
Post by m***@gmail.com
No, I have not spoken to Herb. I was looking for a way to send him a
feedback on his blog or somewhere else related to that proposal. The
closest I found is this group.
And you are right, that is what I am proposing. I think it keeps the
original goal intact but adds a (imo useful) customization point.
There could be a std::throwing_allocator too, if that seems to be useful
to many people.Or at least, given the idea of the polymorphic_allocator, since
C++17, a version of it that throws would be a good thing as well.
On Thursday, October 18, 2018 at 9:15:45 PM UTC-6, Bryce Adelstein Lelbach
Post by Bryce Adelstein Lelbach aka wash
It sounds like what you are suggesting is that instead of making library
* Make them conditionally noexcept if any user defined allocators used
can throw, and
* Make std::allocator and operator new (aka the defaults) noexcept.
The result is the same in the default case; out of memory is fatal. But
if you use a customize allocator that can throw, you get the current
semantics.
This sounds reasonable to me.
Have you spoke to Herb?
Post by m***@gmail.com
In P0709, Herb Sutter proposes a zero-overhead deterministic variation
of the exception mechanism by throwing a value of a size equivalent to two
pointers.
I generally like the proposal a lot. I am doing HPC programming and
micro-controller programming and do see a lot of benefit in squelching
objections to the use of exceptions.
However, when it comes to the treatment of heap exhaustion and, more
importantly, the impact of it on the standard library, I am finding the
proposal to be disturbing.
- For each standard function for which allocation is the only
reportable error, make the function noexcept. (We expect this to result in
making a large majority of functions in the standard library noexcept,
including default and user-replaced ::operator new.)
- For code that wants to handle heap allocation failures, provide
explicit “try to allocate” functions including the existing new(nothrow)
However this approach is disturbing. It is essentially saying to go
back to an equivalent of testing an error code on return of every single
call. Also because it goes against the ideas of writing a single generic
routine for an algorithm because it seems to imply that every time I want
to write an algorithm that involves a standard library function that does a
memory allocation, I should write both a regular version and a try_***
version.
So Herb wants that the vector<T> push_back should be noexcept while the
try_push_back can throw.
Though, I can see the use for having a try_*** in places, I wonder why
he does not suggest to let the allocator used make the decision? Something
void push_back (const value_type& val) throws( can_throw_v<Alloc> ) ;
In my HPC work, I write library in which users can supply a memory
buffer that my code can use. If I run out of memory, it is out of the
question that the code would crash. Instead it should be reported to the
user that she needs to provide a bigger buffer. I can do that by using an
allocator that throws an exception. Using a solution like I suggest above
would allow to still have noexcept if the user is fine with terminate being
called and still allow to handle cases like mine gracefully in a way that I
can report to the caller as they are expecting. If the standard library
always calls terminate on failure of allocation, then I'll have to resort
to not using the standard library, but using a modified clone of it. This
would be ironic, as one of the motivations of his proposal in the first
place is that people are not using the standard library.
--
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
To view this discussion on the web visit
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cc411e93-53a3-4b24-8e02-68fda610c15e%40isocpp.org
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cc411e93-53a3-4b24-8e02-68fda610c15e%40isocpp.org?utm_medium=email&utm_source=footer>
.
--
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/c76e7e32-a6ed-4e8c-9da2-519ca31534a6%40isocpp.org.
m***@gmail.com
2018-10-19 18:37:53 UTC
Permalink
You are right. Wasn't sure it's the most appropriate channel, but I will
email him. Thanks.
Post by Ben Craig
"No, I have not spoken to Herb. I was looking for a way to send him a
feedback on his blog or somewhere else related to that proposal."
Almost all papers include an email address that can be used to provide
feedback. It's a paper "bug" when there is no email address included.
Post by m***@gmail.com
No, I have not spoken to Herb. I was looking for a way to send him a
feedback on his blog or somewhere else related to that proposal. The
closest I found is this group.
And you are right, that is what I am proposing. I think it keeps the
original goal intact but adds a (imo useful) customization point.
There could be a std::throwing_allocator too, if that seems to be useful
to many people.Or at least, given the idea of the polymorphic_allocator, since
C++17, a version of it that throws would be a good thing as well.
On Thursday, October 18, 2018 at 9:15:45 PM UTC-6, Bryce Adelstein
Post by Bryce Adelstein Lelbach aka wash
It sounds like what you are suggesting is that instead of making library
* Make them conditionally noexcept if any user defined allocators used
can throw, and
* Make std::allocator and operator new (aka the defaults) noexcept.
The result is the same in the default case; out of memory is fatal. But
if you use a customize allocator that can throw, you get the current
semantics.
This sounds reasonable to me.
Have you spoke to Herb?
Post by m***@gmail.com
In P0709, Herb Sutter proposes a zero-overhead deterministic variation
of the exception mechanism by throwing a value of a size equivalent to two
pointers.
I generally like the proposal a lot. I am doing HPC programming and
micro-controller programming and do see a lot of benefit in squelching
objections to the use of exceptions.
However, when it comes to the treatment of heap exhaustion and, more
importantly, the impact of it on the standard library, I am finding the
proposal to be disturbing.
- For each standard function for which allocation is the only
reportable error, make the function noexcept. (We expect this to result in
making a large majority of functions in the standard library noexcept,
including default and user-replaced ::operator new.)
- For code that wants to handle heap allocation failures, provide
explicit “try to allocate” functions including the existing new(nothrow)
However this approach is disturbing. It is essentially saying to go
back to an equivalent of testing an error code on return of every single
call. Also because it goes against the ideas of writing a single generic
routine for an algorithm because it seems to imply that every time I want
to write an algorithm that involves a standard library function that does a
memory allocation, I should write both a regular version and a try_***
version.
So Herb wants that the vector<T> push_back should be noexcept while the
try_push_back can throw.
Though, I can see the use for having a try_*** in places, I wonder why
he does not suggest to let the allocator used make the decision? Something
void push_back (const value_type& val) throws( can_throw_v<Alloc> ) ;
In my HPC work, I write library in which users can supply a memory
buffer that my code can use. If I run out of memory, it is out of the
question that the code would crash. Instead it should be reported to the
user that she needs to provide a bigger buffer. I can do that by using an
allocator that throws an exception. Using a solution like I suggest above
would allow to still have noexcept if the user is fine with terminate being
called and still allow to handle cases like mine gracefully in a way that I
can report to the caller as they are expecting. If the standard library
always calls terminate on failure of allocation, then I'll have to resort
to not using the standard library, but using a modified clone of it. This
would be ironic, as one of the motivations of his proposal in the first
place is that people are not using the standard library.
--
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
To view this discussion on the web visit
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cc411e93-53a3-4b24-8e02-68fda610c15e%40isocpp.org
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cc411e93-53a3-4b24-8e02-68fda610c15e%40isocpp.org?utm_medium=email&utm_source=footer>
.
--
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/70908db4-8cc7-41b2-b490-45119b8b5c5f%40isocpp.org.
Bryce Adelstein Lelbach aka wash
2018-10-19 22:28:47 UTC
Permalink
Adding Herb
Post by m***@gmail.com
No, I have not spoken to Herb. I was looking for a way to send him a
feedback on his blog or somewhere else related to that proposal. The
closest I found is this group.
And you are right, that is what I am proposing. I think it keeps the
original goal intact but adds a (imo useful) customization point.
There could be a std::throwing_allocator too, if that seems to be useful
to many people.Or at least, given the idea of the polymorphic_allocator, since
C++17, a version of it that throws would be a good thing as well.
On Thursday, October 18, 2018 at 9:15:45 PM UTC-6, Bryce Adelstein Lelbach
Post by Bryce Adelstein Lelbach aka wash
It sounds like what you are suggesting is that instead of making library
* Make them conditionally noexcept if any user defined allocators used
can throw, and
* Make std::allocator and operator new (aka the defaults) noexcept.
The result is the same in the default case; out of memory is fatal. But
if you use a customize allocator that can throw, you get the current
semantics.
This sounds reasonable to me.
Have you spoke to Herb?
Post by m***@gmail.com
In P0709, Herb Sutter proposes a zero-overhead deterministic variation
of the exception mechanism by throwing a value of a size equivalent to two
pointers.
I generally like the proposal a lot. I am doing HPC programming and
micro-controller programming and do see a lot of benefit in squelching
objections to the use of exceptions.
However, when it comes to the treatment of heap exhaustion and, more
importantly, the impact of it on the standard library, I am finding the
proposal to be disturbing.
- For each standard function for which allocation is the only
reportable error, make the function noexcept. (We expect this to result in
making a large majority of functions in the standard library noexcept,
including default and user-replaced ::operator new.)
- For code that wants to handle heap allocation failures, provide
explicit “try to allocate” functions including the existing new(nothrow)
However this approach is disturbing. It is essentially saying to go
back to an equivalent of testing an error code on return of every single
call. Also because it goes against the ideas of writing a single generic
routine for an algorithm because it seems to imply that every time I want
to write an algorithm that involves a standard library function that does a
memory allocation, I should write both a regular version and a try_***
version.
So Herb wants that the vector<T> push_back should be noexcept while the
try_push_back can throw.
Though, I can see the use for having a try_*** in places, I wonder why
he does not suggest to let the allocator used make the decision? Something
void push_back (const value_type& val) throws( can_throw_v<Alloc> ) ;
In my HPC work, I write library in which users can supply a memory
buffer that my code can use. If I run out of memory, it is out of the
question that the code would crash. Instead it should be reported to the
user that she needs to provide a bigger buffer. I can do that by using an
allocator that throws an exception. Using a solution like I suggest above
would allow to still have noexcept if the user is fine with terminate being
called and still allow to handle cases like mine gracefully in a way that I
can report to the caller as they are expecting. If the standard library
always calls terminate on failure of allocation, then I'll have to resort
to not using the standard library, but using a modified clone of it. This
would be ironic, as one of the motivations of his proposal in the first
place is that people are not using the standard library.
--
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
To view this discussion on the web visit
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cc411e93-53a3-4b24-8e02-68fda610c15e%40isocpp.org
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cc411e93-53a3-4b24-8e02-68fda610c15e%40isocpp.org?utm_medium=email&utm_source=footer>
.
--
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
To view this discussion on the web visit
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b701aa54-f4b6-4d9a-8980-db398aa299e4%40isocpp.org
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b701aa54-f4b6-4d9a-8980-db398aa299e4%40isocpp.org?utm_medium=email&utm_source=footer>
.
--
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAP3wax_iN%2BObzNXg-ONWMkUHR3e_ZDMAdw_EOEf3eH1CkcHu-Q%40mail.gmail.com.
Herb Sutter
2018-10-20 00:07:00 UTC
Permalink
Ack: Got it, thanks! Will merge with other feedback and discussions as they happen over the coming meetings






From: Bryce Adelstein Lelbach aka wash <***@gmail.com>
Sent: Friday, October 19, 2018 3:29 PM
To: std-***@isocpp.org
Cc: Herb Sutter <***@gmail.com>
Subject: Re: [std-proposals] P0709 Heap exhaustion and try_... for standard library.



Adding Herb



On Fri, Oct 19, 2018, 12:18 AM <***@gmail.com <mailto:***@gmail.com> > wrote:

No, I have not spoken to Herb. I was looking for a way to send him a feedback on his blog or somewhere else related to that proposal. The closest I found is this group.



And you are right, that is what I am proposing. I think it keeps the original goal intact but adds a (imo useful) customization point.

There could be a std::throwing_allocator too, if that seems to be useful to many people.Or at least, given the idea of the polymorphic_allocator, since C++17, a version of it that throws would be a good thing as well.

On Thursday, October 18, 2018 at 9:15:45 PM UTC-6, Bryce Adelstein Lelbach wrote:

It sounds like what you are suggesting is that instead of making library functions that can throw unconditionally noexcept, we:



* Make them conditionally noexcept if any user defined allocators used can throw, and

* Make std::allocator and operator new (aka the defaults) noexcept.



The result is the same in the default case; out of memory is fatal. But if you use a customize allocator that can throw, you get the current semantics.



This sounds reasonable to me.



Have you spoke to Herb?



On Wed, Oct 17, 2018, 3:16 PM <***@gmail.com <mailto:***@gmail.com> > wrote:

In P0709, Herb Sutter proposes a zero-overhead deterministic variation of the exception mechanism by throwing a value of a size equivalent to two pointers.



I generally like the proposal a lot. I am doing HPC programming and micro-controller programming and do see a lot of benefit in squelching objections to the use of exceptions.

However, when it comes to the treatment of heap exhaustion and, more importantly, the impact of it on the standard library, I am finding the proposal to be disturbing.

In section 4.3.3 Herb proposes:

* For each standard function for which allocation is the only reportable error, make the function noexcept. (We expect this to result in making a large majority of functions in the standard library noexcept, including default and user-replaced ::operator new.)

* For code that wants to handle heap allocation failures, provide explicit “try to allocate” functions including the existing new(nothrow)

However this approach is disturbing. It is essentially saying to go back to an equivalent of testing an error code on return of every single call. Also because it goes against the ideas of writing a single generic routine for an algorithm because it seems to imply that every time I want to write an algorithm that involves a standard library function that does a memory allocation, I should write both a regular version and a try_*** version.

So Herb wants that the vector<T> push_back should be noexcept while the try_push_back can throw.
void push_back (const value_type& val) throws( can_throw_v<Alloc> ) ;
In my HPC work, I write library in which users can supply a memory buffer that my code can use. If I run out of memory, it is out of the question that the code would crash. Instead it should be reported to the user that she needs to provide a bigger buffer. I can do that by using an allocator that throws an exception. Using a solution like I suggest above would allow to still have noexcept if the user is fine with terminate being called and still allow to handle cases like mine gracefully in a way that I can report to the caller as they are expecting. If the standard library always calls terminate on failure of allocation, then I'll have to resort to not using the standard library, but using a modified clone of it. This would be ironic, as one of the motivations of his proposal in the first place is that people are not using the standard library.
--
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-***@isocpp.org <mailto:std-***@isocpp.org> .
To post to this group, send email to std-***@isocpp.org <mailto:std-***@isocpp.org> .
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cc411e93-53a3-4b24-8e02-68fda610c15e%40isocpp.org <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cc411e93-53a3-4b24-8e02-68fda610c15e%40isocpp.org?utm_medium=email&utm_source=footer> .
--
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+***@isocpp.org <mailto:std-proposals+***@isocpp.org> .
To post to this group, send email to std-***@isocpp.org <mailto:std-***@isocpp.org> .
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b701aa54-f4b6-4d9a-8980-db398aa299e4%40isocpp.org <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b701aa54-f4b6-4d9a-8980-db398aa299e4%40isocpp.org?utm_medium=email&utm_source=footer> .
--
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/008801d46808%24d33a08d0%2479ae1a70%24%40gmail.com.
p***@lib.hu
2018-10-19 21:27:18 UTC
Permalink
However this approach is disturbing. It is essentially saying to go back
to an equivalent of testing an error code on return of every single call.
Also because it goes against the ideas of writing a single generic routine
for an algorithm because it seems to imply that every time I want to write
an algorithm that involves a standard library function that does a memory
allocation, I should write both a regular version and a try_*** version.
So Herb wants that the vector<T> push_back should be noexcept while the
try_push_back can throw.
Though, I can see the use for having a try_*** in places, I wonder why he
does not suggest to let the allocator used make the decision?
I didn't read the proposal (and it is a long way from final so by the time
I do it may have changed that part ;) so just my general thoughts:

The OOM handling as we have it today is indeed suboptimal for many many
environmants. And making all those functions nothrow looks like progress in
the good direction. The throwing approach is only good for those who
actually handle it and keep the program going. My past experience on
several platforms is that the program just never survived such an attempt,
it failed in some OS call or just got killed. The tactics to have some
pre-reserved memory and release that to manage the small portion of clean
exit was futile too, whatever caused the OOM condition in the first place
grabbed the chunk.

Wherever I can I arrange OOM as a fatal failure with direct terminate.
(maybe would allow a "stall" option in the new handler if all memory was
obtained through that, but it realistically isn't).

The places where I really expect OOM and want retry are really rare, and
belong to a special case of grabbing some big chunk, amount subject to
available memory. For what I'd really appreciate a proper interface without
throwing, that I could supply with a callback for haggling, and would give
me the memory chunk and the brokered size.

And to help out the code that actually likes the current interface and
wants to deal with catching bad_alloc, I'm positive we can think up several
ways from specific interface additions (i.e vector does not really need to
duplicate all the interface, just have a try_reserve) or some control flags
at global/thread/object level to alter behavior. If the replacable
new_handler is not enough.
--
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/7946c93f-6bbd-42e4-b037-2784e93e537a%40isocpp.org.
Florian Weimer
2018-10-20 09:20:31 UTC
Permalink
Post by p***@lib.hu
The OOM handling as we have it today is indeed suboptimal for many many
environmants. And making all those functions nothrow looks like progress in
the good direction. The throwing approach is only good for those who
actually handle it and keep the program going. My past experience on
several platforms is that the program just never survived such an attempt,
it failed in some OS call or just got killed.
It's a configuration matter. For example, under Linux, if you want
malloc to fail when there is no memory available, instead of
terminating random processes, you can set the vm.overcommit_memory=2
sysctl. (I believe that on most other systems, this behavior is
actually the default.)

There are also examples of run-times which impose their own memory
allocation limits (such as PostgreSQL). I have seen servers survive
out-of-memory situations reliably. We also tend to get angry bug
reports if we have bugs on memory allocation failure paths in glibc
(such as not checking for malloc failure and reporting it to the
caller, but crashing due to a null pointer dereference). Of course,
there are many counterexamples of systems which do not deal properly
with memory allocation failures, but once a basic system component
gives up on this matter, you can never add it back again at a higher
level, at least not reliably.

Now one could argue that all these are written in C and applications
where resource allocation can fail and need recovery (beyond mere
process termination) are not C++'s domain and should instead use C, or
at least not the C++ standard library. But this is not the feeling I
get from skimming the proposals, many of which imply that there should
not be a lower-level language than C++, and C++ should be up to these
tasks.

Furthermore, until the recent almost universal anti-exception stance,
C++ seemed to me a particularly good language for writing such systems
because due to RAII, you had a decent chance of returning to a
known-good state after an unexpected exception. C++ implementations
even tend to have emergency memory reservations so that they can throw
std::bad_alloc even if the regular heap is exhausted.
Post by p***@lib.hu
And to help out the code that actually likes the current interface and
wants to deal with catching bad_alloc, I'm positive we can think up several
ways from specific interface additions (i.e vector does not really need to
duplicate all the interface, just have a try_reserve) or some control flags
at global/thread/object level to alter behavior. If the replacable
new_handler is not enough.
Realistically, you will need to support libraries with do both forms
of error handling in the same process. Maybe they even have to
interchange std::string objects. I'm not sure if flags are going to
work for this, and certainly not global, process-wide properties.

I'm not even sure if changes are needed. Even today, people can get
process termination on std::bad_alloc if they declare the functions
they write as noexcept, I suppose. (This is the strength of unchecked
exceptions: If you don't want to deal with them, at least you get a
clean error, and you don't need to spend mental effort on ways to
sweep the error under the rug, such as returning made-up return values
because there are insufficient resources to compute the correct
result.)
--
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/87o9bpht40.fsf%40mid.deneb.enyo.de.
p***@lib.hu
2018-10-20 12:18:05 UTC
Permalink
2018. október 20., szombat 11:20:36 UTC+2 időpontban Florian Weimer a
Post by p***@lib.hu
Post by p***@lib.hu
The OOM handling as we have it today is indeed suboptimal for many many
environmants. And making all those functions nothrow looks like progress
in
Post by p***@lib.hu
the good direction. The throwing approach is only good for those who
actually handle it and keep the program going. My past experience on
several platforms is that the program just never survived such an
attempt,
Post by p***@lib.hu
it failed in some OS call or just got killed.
It's a configuration matter. For example, under Linux, if you want
malloc to fail when there is no memory available, instead of
terminating random processes, you can set the vm.overcommit_memory=2
sysctl. (I believe that on most other systems, this behavior is
actually the default.)
There were many articles around that in the 90s. Concluding that with the
default practice of existing linux-like system it is just impossible to
have a conforming C++ system. As with the memory overcommit thingy you get
the memory, no null return, no bac_alloc, no indication, then you just get
a crash accessing arr[42] -- when the system can not summon a memory
page. The other common variant was very funny too, that just killed
random processes on a whim, yours if you won the lottery.

C++ seemed to me a particularly good language for writing such systems
Post by p***@lib.hu
because due to RAII, you had a decent chance of returning to a
known-good state after an unexpected exception. C++ implementations
even tend to have emergency memory reservations so that they can throw
std::bad_alloc even if the regular heap is exhausted.
In theory it definitely is. In practice, not that much. My experience on
Windows with MFC: It has a fairly centralized system to grab memory. It
throws CMemoryException * on failure. The attached object is preallocated
so from throw point you're supposedly fine.

In practice you started the elephant (the memory stress app form win sdk)
and your app crashed. And so did winword and all the other programs you
had. O,O
If you managed to the exception handler and tried as much as a MessageBox,
it likely had missing buttons, missing text, block characters instead of
text or just crash. Pick your poison. I felt lucky if could just close my
files and exit let alone hope to start something else.

Meanwhile in other systems where memory was actually scarce using the
regular heap on the go was out of question. The components grabbed their
full memory on start and used that till exit.
--
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/aa08220a-4bd1-452d-86b3-021355f15e29%40isocpp.org.
Continue reading on narkive:
Loading...