Skip to content

[clang-tidy] Check request: don't capture this by a field of default copyable class #120863

@denzor200

Description

@denzor200

Assume the user defined class:

struct A {
   std::string content;
   std::function<void()> captured;
   
   A() {
    captured = 
        [this]() { // INCORRECT
            perform();
        };
   }

   void perform() { std::cout << content << std::endl; }
};

Since it's copy constructor was generated by the compiler, it's behaviour might be unexpected for some user and even can produce a crash with SIGSEGV:

A a;
a.content = "Hello world";
a.captured();

A a1 = a;
a1.content = "Test";
a1.captured(); // will print "Hello world" which might be unexpected
auto a = std::make_unique<A>();
a->content = "Hello world";
a->captured();

auto b = std::make_unique<A>(*a);
a.reset();
b->content = "Ooooups!";
b->captured(); // UB

The way to fix it is to provide manually written copy constructor and assignment operator:

A(const A& oth)
    : content(oth.content)
    , captured([this](){perform();}) {}
A& operator=(const A& oth) {
    if (this != &oth) {
        content = oth.content;
        captured = [this](){perform();};
    }
}

Making you class noncopyable also protect you from the bug:

A(const A& oth) = delete;
A& operator=(const A& oth) = delete;

But before you fix it you must discover it in the code, so the clang-tidy check in bugprone section would be nice addition.

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions