Search code examples
c++move-semantics

Can I mark a moved variable as no longer usable and receive a compiler warning if I do use it?


Sometimes in a function I use std::move to pass on a variable I'm no longer using, like this:

void f(std::vector<int> v)
{
    for (int i: v)
    {
        std::cout << i << ", ";
    }
}

void main()
{
    std::vector<int> v(1000);
    std::fill(v.begin(), v.end(), 42);
    f(std::move(v));
}

I understand the std::move leaves my vector in a valid state, so I could call v.clear() and reuse it if I wanted to do so. But in a long function I may later add more code to it and forget that I've lost the data with my move function, introducing a bug.

Is there some kind of compiler instruction I can put after the move to warn me not to reuse this variable? Like this:

void main()
{
    std::vector<int> v(1000);
    std::fill(v.begin(), v.end(), 42);
    f(std::move(v));
    #pragma mark_unusable(v);

    // This should trigger a compiler warning
    v[5] = 10;
}

Solution

  • Partial answer: you can use clang-tidy with its bugprone-use-after-move check. This does not catch v.clear() in your example, but at least other cases instead. Example:

    clang-tidy -checks=bugprone-use-after-move your-file.cpp
    

    When you add a second f(std::move(v)); after the first invocation, this gives you

    your-file.cpp:15:17: warning: 'v' used after it was moved [bugprone-use-after-move]
    f(std::move(v));
                ^
    your-file.cpp:14:5: note: move occurred here
    f(std::move(v));
    ^