C++ Logo

std-proposals

Advanced search

Re: [std-proposals] int Func(void) noreentry(-1)

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Sun, 12 Feb 2023 21:05:44 +0000
On Thu, Feb 2, 2023 at 5:49 PM Thiago Macieira wrote:

> > This new feature could be kept simple, or tt could made be very
> > complex with extra parameters to do stuff like:
> > * Prevent reentry by other threads but not by the same thread
> > * Prevent reentry by the same thread but not by other threads
> > * Prevent reentry by all threads except the one with the specified
> > thread::id
>
> You've mostly implemented this already as library solutions.
>
> So please explain why you think this should be a core language change. What
> can the core language do better than a library solution could?


I haven't got a library solution. Needing to add 'atomic_flag' objects
to your classes and functions, and then manipulating them as
appropriate, isn't simple and straight-forward, and it's not a
'library solution' in the simplistic sense of just including a header
file and then using an encapsulated class.

I'll try to explain what I mean here by making a comparison with
another of C++'s features. In C++, we can have a static object inside
a function, and even if our program is multi-threaded, the
aforementioned static object will only ever be constructed once (and
the other concurrent threads will wait for it to be
fully-constructed). So this means I can write really simple code like
the following:

void Func(int const arg)
{
    static std::string str = std::to_string(arg);

    // The rest of the function goes here
}

Now let's say that the C++ Standard were to change so that it no
longer ensures that static objects inside functions get initialised
properly in multi-threaded programs. I would then have to complicate
my code as follows:

std::atomic_flag is_initialising = ATOMIC_FLAG_INIT;
std::atomic<bool> is_initialised = false;
std::optional<std::string> opt_str;

void Func(int const arg)
{
    if ( false == is_initialising.test_and_set() )
    {
        opt_str.emplace( std::to_string(arg) );
        is_initialised = true;
    }

    is_initialised.wait(false);

    std::string &str = opt_str.value();

    // The remainder of the function goes here
}

This new code I've written does exactly what the old code does. So you
might argue that I already have a library solution, and that I don't
need a core language feature.
I think over 95% of expert C++ programmers would agree though that
it's better that we have the core language feature.

I'm making a similar argument here for "noreentry". Sure, we can use
atomic_flags and atomic booleans to get the job done -- but it would
be better if it were all managed for us behind the scenes by the
compiler, for two reason:
(1) Less typing for us, less thinking, it's just easier and quicker
(2) Less chance of introducing a bug

Received on 2023-02-12 21:05:54