On Tue, 16 Jul 2024 at 19:12, Jonathan Wakely <jwakely....@gmail.com> wrote:
>
>
>
> On Tue, 16 Jul 2024, 18:51 M.C.A. (Marco) Devillers via Gcc, 
> <gcc@gcc.gnu.org> wrote:
>>
>> Document number:  SCF4C++00
>> Date:  2024-7-16
>> Audience:  GCC email list
>> Reply-to:  marco.devill...@gmail.com, gcc@gcc.gnu.org
>>
>> I. Introduction
>>
>> Because C++ smart pointers are based on RAII it is easy to trigger an
>> overflow of the C stack since destructors call each other. Smart
>> pointers are supposed to be safe, smart pointers are likely to be used
>> extensively in the future, and this behaviour could make a large
>> number of C++ programs core dump unexpectedly.
>> This proposal is to remove this behaviour from GCCs standard library
>
>
> Where does it exist in the library?
>
> The problem in your program is easily avoided, without changing the standard 
> or GCC's implementation of the standard library.
>
>> and also showcases a small trick by which that can be done.
>>
>> II. Motivation and Scope
>>
>> We all want smart pointers since they allow for easy and safe memory
>> management, this desire is only expected to increase over the
>> following decades.
>>
>> However due to RAII semantics it's easy to trigger an overflow of the
>> C stack once garbage goes out of scope. Observe the following trivial
>> program:
>>
>> #include <iostream>
>> #include <memory>
>>
>> struct list_node {
>>    using ptr = std::unique_ptr<list_node>;
>>    ~list_node() {
>>    }
>>
>>    int x;
>>    ptr next;
>> };
>>
>> int main() {
>>    list_node::ptr next = nullptr;
>>
>>    for(int i = 0; i < 100000; ++i) { // decrease value to see it not segfault
>>        next = list_node::ptr(new list_node{i, std::move(next)});
>>    }
>> }
>>
>> Cascading frees will make this program core dump depending the size of
>> the list. Please note, that that program will segfault on for current
>> data-driven days relatively tiny sizes.
>
>
> So don't do that then. It's easy to add a loop to clean up the list. Or 
> create an actual list class to manage the nodes and do that loop in its 
> destructor. Nobody is forced to define a list only in terms of nodes, rather 
> than a list class that manages the nodes.

Or you can put the loop in the node destructor:

   ~list_node() {
     while (next)
       next = std::move(next->next);
   }

Unlike your cleanup stack, this doesn't require any additional memory
allocation or synchronization.

Reply via email to