[Bug libstdc++/69879] Create a pointer to the default operator new and delete

redi at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Fri Jan 17 14:05:00 GMT 2020


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69879

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |https://gcc.gnu.org/bugzill
                   |                            |a/show_bug.cgi?id=86013

--- Comment #11 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Stated differently, the original problem is "the new-handler can only prevent
looping by throwing an exception or terminating, which isn't appropriate for
enironments using -fno-exceptions".

The first solution (proposed on the mailing list) was to add a custom build
mode that prevents looping, but makes operator new non-conforming.

The solution proposed in comment 0 is to allow users to override new/delete
with their desired behaviour but still call the default versions. The more I
think about it, the more I dislike that. The new-handler is a global variable,
so switching it back and forth like that is completely incompatible with
multithreaded programs. As soon as two threads use new at the same time, you
have no idea which new-handler will be used by __default_operator_new. I think
the approach is completely untenable. Also, it would rely on GNU-specific
symbols that only exist in libstdc++, so those symbols are completely
redundant. The defaults in libstdc++ just use malloc. Fact. If you have to
replace new anyway then just make it use malloc directly, instead of relying on
__default_operator_new, which is just going to call malloc.

I think the only sensible approach here is "make nothrow-new work without
exceptions". So don't call the throwing new and try to catch the exception, and
don't assume the new-handler will throw when it couldn't make memory available.

PR 86013 comment 8 shows a possible way to implement the check here:

  if ( /* operator new has been replaced */ )
    return ::operator new(sz);


More information about the Gcc-bugs mailing list