C & C++

C & C++

Made by DeepSource

Unnecessary copy of non-trivially copyable type CXX-P2005

Performance
Major

Copying an object is an expensive operation, especially if the type of the object is not trivial to copy. To avoid creating an unnecessary copy of such object, use const references.

A trivially copyable type is one that can be safely copied and moved using memcpy and memmove. This means that the type has a trivial copy constructor, a trivial copy assignment operator, and a trivial destructor. Examples of trivially copyable types include:

  • Scalar types (e.g int, float)
  • POD (Plain Old Data) types (e.g. structs and arrays containing only trivially copyable types)
  • Pointers to trivially copyable types

A class or struct is considered a POD type if it is trivially copyable and satisfies certain other constraints such as having no user-defined constructors, no private or protected non-static data members, no virtual functions, and no virtual base classes.

Bad practice

// Example 1: Using strings
const string& getStr();
void do_it() {
    const string s = getStr(); // unnecessary string copy
    // note: `s` can never be modified here
}

// Example 2: Non-trivally copyable type
class A {
    A (const A& a); // A used-defined copy constructor makes this class non-trival to copy
    const void foo() const; // A const method
};

const A& getRefToA();

void do_it(const Foo& foo) {
    A a1 = getRefToA(); // `a1` is never used as a mutable, and still copied. This results in drop in performance.
    a1.foo();

    A a2 = a1; // An identical expensive copy
    a2.foo();
}

Recommended

// Example 1: Using strings
const string& getStr();
void do_it() {
    const string& s = getStr(); // Avoiding copy with const reference
}

// Example 2: Non-trivally copyable type
class A {
    A (const A& a); // A used-defined copy constructor makes this class non-trival to copy
    const void foo() const; // A const method
};

A& getRefToA();

void do_it(const Foo& foo) {
    const A& a1 = getRefToA(); // Avoiding copy with const reference
    a1.foo();

    const A& a2 = a1;
    a2.foo();
}