Main Content

AUTOSAR C++14 Rule A12-8-7

Assignment operators should be declared with the ref-qualifier &

Since R2020b

Description

Rule Definition

Assignment operators should be declared with the ref-qualifier &.

Rationale

You can use ref-qualifiers to specify whether a function or operator applies to lvalues or rvalues. Functions or operators that apply to lvalues have the ref-qualifier &. Functions and operators that apply on rvalues have the ref-qualifier && at the end of their declaration.

Built-in assignment operators in C++ accept only lvalues as input parameters. If user-defined assignment operators take both rvalue and lvalue as input parameters, it can cause confusion and errors. Consider this code where the user-defined assignment operator for the class obj accepts both rvalues and lvalues as input parameters.

class obj{
	obj& operator=(Obj const&){
		//...
		return *this;
	}
	//...
};

int main(){
	int i,j,k;
	obj a,b,c;

	if((i+j)=k) // compilation error
	//...
	if((a+b)=c) // silent error
	//...
}

  • In the first if statement, the equal-to operator (==) is written as an assignment operator (=) because of a typographical error. Because the built-in assignment operator for int does not accept rvalues as input, the statement (i+j) = k causes a compilation error.

  • The condition for the second if statement contains a similar error. Because the user-defined assignment operator for class obj accepts both lvalues and rvalues as input, the statement (a+b) = c compiles without error. The if block executes unexpectedly, resulting in a silent bug.

To avoid errors and confusion, specify that assignment operators take only lvalues as input parameters by adding the ref-qualifier & to their declaration.

Polyspace Implementation

Polyspace® flags user-defined assignment, compound assignment, increment, and decrement operators when:

  • They do not have the ref-qualifier & in their declaration.

  • They are member functions of a class.

  • They are not declared as = delete.

Because ref-qualifiers are applicable only to nonstatic member functions, this rule does not apply to nonmember assignment operators.

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 example shows how Polyspace flags assignment operators and increment or decrement operators when their declarations do not specify the ref-qualifier &.

#include<cstdint>
class Obj
{
public:
	Obj() = default;
	Obj& operator=(Obj const&) & = default; //Compliant    
	Obj& operator=(Obj&&) & = default;      //Compliant    
	Obj& operator++() & noexcept;           //Compliant    
	Obj& operator--()  noexcept;            //Noncompliant 
	Obj& operator<<=(Obj const&) noexcept;  //Noncompliant   
	Obj& operator>>=(Obj const&) & noexcept;//Compliant   
	Obj& operator+=(Obj const&)&;           //Compliant
	Obj& operator-=(Obj const&);            //Noncompliant
	Obj& operator*=(Obj const&)= delete;    //Compliant
	Obj& operator+(Obj const&)&;            //Compliant  
};

Obj& operator|=(Obj& f,const std::int32_t i) // Rule does not apply 
{
	return f;
}

Obj& Obj::operator+=(Obj const&) &  // Polyspace flags the declaration 
{
	return *this;
}
Obj F1() noexcept
{
	return Obj{};
}
int main()
{
	Obj c;
	//F1() += c; // Compilation Error
	//F1() = c; // Compilation Error
	F1() -= c; // Silent Bug
}

In main(), the assignment operators +=, -=, and = are used with an rvlaue input. Because the declarations of the operators += and = specify the ref-qualifier &, using these operators with an rvalue input results in a compilation failure. The operator -= is declared without the reference qualifier &. Using this operator with an rvalue input creates a silent bug.

  • Polyspace flags nondeleted member assignment operators, increment operators, and decrement operators that do not specify the ref-qualifier & in their declarations.

  • When a member assignment operator is declared without the reference qualifier & in a class and defined elsewhere, Polyspace flags the declaration.

  • Polyspace does not flag nonmember operators without the ref-qualifier & because this rule applies only to nonstatic member functions.

  • Polyspace does not flag deleted operators because using the ref-qualifier & on a deleted operator has no impact on the code.

Check Information

Group: Special member functions
Category: Advisory, Automated

Version History

Introduced in R2020b