C++ Logo

std-proposals

Advanced search

[std-proposals] Force compilers to warn about double moves

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Thu, 22 Jun 2023 14:30:05 +0100
There's talk lately about a few different proposals to alleviate the
need for 'move' and 'forward'. This kinda indicates that people are
getting a little fed up with all the moving and forwarding -- or at
least fed up with the syntax.

But anyway, without regard to any of those proposals, just as
something totally separate, I want to propose the following:

Make it compulsory for a compiler to issue a diagnostic (and possibly
also terminate compilation) in the following scenario:

    void Func(SomeClass &&obj)
    {
        SomeOtherFunc( move(obj) );

        AndAgainSomeOtherFunction( move(obj) );
    }

So if an object is moved or forwarded more than once inside the body
of a function, the compiler must tell you:

    <source>: In function 'void Func(SomeClass &&obj)':
       warning: R-value possibly moved more than once
    <source>:3:20 first possible move
       20 | SomeOtherFunc( move(obj) );
    <source>:5:6: second possible move
       32 | AndAgainSomeOtherFunction( move(obj) );

I use the word 'possible' in the diagnostic message because you could
have code like:

    void Func(SomeClass &&obj)
    {
        if ( some_global_boolean ) SomeOtherFunc( move(obj) );

        AndAgainSomeOtherFunction( move(obj) );
    }

If we were to have this new language feature, it would somewhat
alleviate the possibility of introducing double-move bugs (as Arthur
mentioned yesterday).

If we were to mandate that the compiler must also terminate
compilation, then maybe we should introduce a new way of overriding
this feature, perhaps something like:

    void Func(SomeClass &&obj)
    {
        SomeOtherFunc( std::move(obj) );

        AndAgainSomeOtherFunction( std::override_multi_move(obj) );
    }

or if we want it to also work when casting to "T&&", then we could
make it a core language feature as follows:

    void Func(SomeClass &&obj)
    {
        SomeOtherFunc( (SomeClass&&)obj );

        AndAgainSomeOtherFunction( (override SomeClass&&)obj );
    }

This feature I'm proposing would be useful for the C++ language as it
is today in 2023, even if the language weren't to change. But it will
be even more useful if a future proposal is accepted to do away with
the need for 'move' and 'forward'.

Received on 2023-06-22 13:30:17