Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.clear();
}
like image 310
Tim MB Avatar asked Sep 30 '19 07:09

Tim MB


People also ask

How do I get rid of the unused variable warning?

If there are a large number of unused variables or functions, which can happen with ported code, you can add the -Wno-unused compiler option to your makefile. This option suppresses all unused warnings.

When should we use std:: move?

std::move is used to indicate that an object t may be "moved from", i.e. allowing the efficient transfer of resources from t to another object. In particular, std::move produces an xvalue expression that identifies its argument t . It is exactly equivalent to a static_cast to an rvalue reference type.

How does move work c++?

Move constructor moves the resources in the heap, i.e., unlike copy constructors which copy the data of the existing object and assigning it to the new object move constructor just makes the pointer of the declared object to point to the data of temporary object and nulls out the pointer of the temporary objects.


1 Answers

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));
^
like image 60
lubgr Avatar answered Oct 16 '22 06:10

lubgr