Main Content

AUTOSAR C++14 Rule A12-8-1

Move and copy constructors shall move and respectively copy base classes and data members of a class, without any side effects

Since R2021a

Description

Rule Definition

Move and copy constructors shall move and respectively copy base classes and data members of a class, without any side effects.

Rationale

The expected behavior of move and copy constructors is:

  • They move or copy the base classes and data members.

  • The move constructor sets the source object into a valid state.

Authoring move or copy constructors that have additional side effects might cause these issues:

  • Performance: Move and copy constructors are frequently called by standard template library (STL) algorithms and containers. Performance overhead in these constructors caused by side effects can accumulate and affect the performance of your code.

  • Unexpected behavior: Because compilers might omit calls to copy constructors to optimize the code, the number of times a copy constructor might be invoked is indeterminate. As a result, the side effects of a copy constructor might produce unexpected behavior.

Polyspace Implementation

In the body of a copy or move constructor, Polyspace® does not flag these operations:

  • Copy or move assignments.

  • Relational or comparison operations.

  • Modification of the source object in a move operation.

  • Calls to the function std::swap or equivalent user-defined noexceot swap functions. Polyspace identifies functions that these signatures as swap functions: void T::swap(T&) or void [N::]swap(T&, T&). The first signature represents a member function of class T that takes one argument. The second signature represents a nonmember or static function in the namespace N that takes two arguments. The name swap can be case-insensitive and prefixed or postfixed by underscores.

  • Assignment and modification of static variables.

Polyspace flags any other operations in a copy or move constructor as unwanted side effect. For instance, a call to a user-defined swap function is considered an unwanted side effect if the swap function is not noexcept. For a similar rule on copy and move assignment operator, see AUTOSAR C++14 Rule A6-2-1.

Troubleshooting

If you expect a rule violation but Polyspace does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

This code shows how Polyspace flags move and copy constructors that have side effects.

#include<cstdint>
#include <utility>
#include<iostream>
class B
{
public:
	// Implementation
	B(B&& oth) : ptr(std::move(oth.ptr)) // Noncompliant
	{
		oth.ptr = nullptr; // Does not have a side effect
		std::cout<<"Moved"; //Has a side effect
	}
	~B()
	{
		delete ptr;
	}

private:
	std::int32_t* ptr;
};
class C
{
public:
	C(int t=0) : x(t) {}
	C(const C& oth): x(oth.x)  // Noncompliant
	{
		//...
		x = oth.x % 2;  // Has a side effect
		count++; //Not a side effect
	}

private:
	std::int32_t x;
	static std::int32_t count;
};
class D
{
public:

	D(const D& oth): x(oth.x)  // Noncompliant
	{
		D tmp(oth);
		_swap_(tmp);
	}
	void _swap_(D& rhs){ //Might raise exceptions
		//...
	}
private:
	std::int32_t x;
	static std::int32_t count;
};

  • As a side effect, the move constructor of class B prints a string into the output stream. This side effect adds performance overhead to the move operation. Polyspace flags the move assignment operator and highlights the statement. Setting the moved-from object oth.ptr to nullptr is not a side effect.

  • The copy constructor of the class C modifies the data member x of the source object. This side effect adds performance overhead. Unexpected change to data members during move and copy operations can make the code incompatible with the standard template library and introduce errors during development. Polyspace flags the copy assignment operator and highlights the statement x = oth.x % 2. Incrementing the static variable count is not a side effect.

  • The copy constructor of the class D calls a user-defined swap function called _swap_. This swap function is not noexcept. If an exception is raised from _swap_, the exception is an unexpected side effect of the copy constructor. Polyspace flags the copy constructor as noncompliant with this rule. Use user-defined swap functions that are noexcept.

Check Information

Group: Special member functions
Category: Required, Automated

Version History

Introduced in R2021a