This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Assignment operators
- 8 contributors
expression assignment-operator expression
assignment-operator : one of = *= /= %= += -= <<= >>= &= ^= |=
Assignment operators store a value in the object specified by the left operand. There are two kinds of assignment operations:
simple assignment , in which the value of the second operand is stored in the object specified by the first operand.
compound assignment , in which an arithmetic, shift, or bitwise operation is performed before storing the result.
All assignment operators in the following table except the = operator are compound assignment operators.
Assignment operators table
Operator keywords.
Three of the compound assignment operators have keyword equivalents. They are:
C++ specifies these operator keywords as alternative spellings for the compound assignment operators. In C, the alternative spellings are provided as macros in the <iso646.h> header. In C++, the alternative spellings are keywords; use of <iso646.h> or the C++ equivalent <ciso646> is deprecated. In Microsoft C++, the /permissive- or /Za compiler option is required to enable the alternative spelling.
Simple assignment
The simple assignment operator ( = ) causes the value of the second operand to be stored in the object specified by the first operand. If both objects are of arithmetic types, the right operand is converted to the type of the left, before storing the value.
Objects of const and volatile types can be assigned to l-values of types that are only volatile , or that aren't const or volatile .
Assignment to objects of class type ( struct , union , and class types) is performed by a function named operator= . The default behavior of this operator function is to perform a member-wise copy assignment of the object's non-static data members and direct base classes; however, this behavior can be modified using overloaded operators. For more information, see Operator overloading . Class types can also have copy assignment and move assignment operators. For more information, see Copy constructors and copy assignment operators and Move constructors and move assignment operators .
An object of any unambiguously derived class from a given base class can be assigned to an object of the base class. The reverse isn't true because there's an implicit conversion from derived class to base class, but not from base class to derived class. For example:
Assignments to reference types behave as if the assignment were being made to the object to which the reference points.
For class-type objects, assignment is different from initialization. To illustrate how different assignment and initialization can be, consider the code
The preceding code shows an initializer; it calls the constructor for UserType2 that takes an argument of type UserType1 . Given the code
the assignment statement
can have one of the following effects:
Call the function operator= for UserType2 , provided operator= is provided with a UserType1 argument.
Call the explicit conversion function UserType1::operator UserType2 , if such a function exists.
Call a constructor UserType2::UserType2 , provided such a constructor exists, that takes a UserType1 argument and copies the result.
Compound assignment
The compound assignment operators are shown in the Assignment operators table . These operators have the form e1 op = e2 , where e1 is a non- const modifiable l-value and e2 is:
an arithmetic type
a pointer, if op is + or -
a type for which there exists a matching operator *op*= overload for the type of e1
The built-in e1 op = e2 form behaves as e1 = e1 op e2 , but e1 is evaluated only once.
Compound assignment to an enumerated type generates an error message. If the left operand is of a pointer type, the right operand must be of a pointer type, or it must be a constant expression that evaluates to 0. When the left operand is of an integral type, the right operand must not be of a pointer type.
Result of built-in assignment operators
The built-in assignment operators return the value of the object specified by the left operand after the assignment (and the arithmetic/logical operation in the case of compound assignment operators). The resultant type is the type of the left operand. The result of an assignment expression is always an l-value. These operators have right-to-left associativity. The left operand must be a modifiable l-value.
In ANSI C, the result of an assignment expression isn't an l-value. That means the legal C++ expression (a += b) += c isn't allowed in C.
Expressions with binary operators C++ built-in operators, precedence, and associativity C assignment operators
Was this page helpful?
Additional resources
- C++ Data Types
- C++ Input/Output
- C++ Pointers
- C++ Interview Questions
- C++ Programs
- C++ Cheatsheet
- C++ Projects
- C++ Exception Handling
- C++ Memory Management
Assignment Operators In C++
In C++, the assignment operator forms the backbone of many algorithms and computational processes by performing a simple operation like assigning a value to a variable. It is denoted by equal sign ( = ) and provides one of the most basic operations in any programming language that is used to assign some value to the variables in C++ or in other words, it is used to store some kind of information.
The right-hand side value will be assigned to the variable on the left-hand side. The variable and the value should be of the same data type.
The value can be a literal or another variable of the same data type.
Compound Assignment Operators
In C++, the assignment operator can be combined into a single operator with some other operators to perform a combination of two operations in one single statement. These operators are called Compound Assignment Operators. There are 10 compound assignment operators in C++:
- Addition Assignment Operator ( += )
- Subtraction Assignment Operator ( -= )
- Multiplication Assignment Operator ( *= )
- Division Assignment Operator ( /= )
- Modulus Assignment Operator ( %= )
- Bitwise AND Assignment Operator ( &= )
- Bitwise OR Assignment Operator ( |= )
- Bitwise XOR Assignment Operator ( ^= )
- Left Shift Assignment Operator ( <<= )
- Right Shift Assignment Operator ( >>= )
Lets see each of them in detail.
1. Addition Assignment Operator (+=)
In C++, the addition assignment operator (+=) combines the addition operation with the variable assignment allowing you to increment the value of variable by a specified expression in a concise and efficient way.
This above expression is equivalent to the expression:
2. Subtraction Assignment Operator (-=)
The subtraction assignment operator (-=) in C++ enables you to update the value of the variable by subtracting another value from it. This operator is especially useful when you need to perform subtraction and store the result back in the same variable.
3. Multiplication Assignment Operator (*=)
In C++, the multiplication assignment operator (*=) is used to update the value of the variable by multiplying it with another value.
4. Division Assignment Operator (/=)
The division assignment operator divides the variable on the left by the value on the right and assigns the result to the variable on the left.
5. Modulus Assignment Operator (%=)
The modulus assignment operator calculates the remainder when the variable on the left is divided by the value or variable on the right and assigns the result to the variable on the left.
6. Bitwise AND Assignment Operator (&=)
This operator performs a bitwise AND between the variable on the left and the value on the right and assigns the result to the variable on the left.
7. Bitwise OR Assignment Operator (|=)
The bitwise OR assignment operator performs a bitwise OR between the variable on the left and the value or variable on the right and assigns the result to the variable on the left.
8. Bitwise XOR Assignment Operator (^=)
The bitwise XOR assignment operator performs a bitwise XOR between the variable on the left and the value or variable on the right and assigns the result to the variable on the left.
9. Left Shift Assignment Operator (<<=)
The left shift assignment operator shifts the bits of the variable on the left to left by the number of positions specified on the right and assigns the result to the variable on the left.
10. Right Shift Assignment Operator (>>=)
The right shift assignment operator shifts the bits of the variable on the left to the right by a number of positions specified on the right and assigns the result to the variable on the left.
Also, it is important to note that all of the above operators can be overloaded for custom operations with user-defined data types to perform the operations we want.
Similar Reads
- CSS min-height Property The min-height property in CSS is used to set the minimum height of an element. The min-height property is used when the content of the element is smaller than the min-height and if the content is larger than the min-height then it has no effect. This property ensures that the value of the height pr 3 min read
- How to Center an Element in jQuery ? Centering elements in a webpage is a common task for web developers, often involving CSS. However, certain scenarios might require dynamically centering elements using JavaScript or jQuery, especially when dealing with dynamic content sizes or responsive designs. jQuery, a fast, small, and feature-r 3 min read
- Blaze UI Containers Vertical Alignment Blaze UI is a CSS open-source framework. It is a lightweight UI toolkit and provides great tools for building customized and scalable applications. It can work with any framework that exists. It can adapt to any ecosystem. All designs or CSS are mobile-first and hence responsive. Its project is avai 2 min read
- CSS height Property The height property is used to set the height of an element. The height property does not contain padding and margin and border of the element. Syntax: height: auto|length|initial|inherit;Default Value: auto Property Values: auto: It is used to set the height property to its default value. If the he 3 min read
- CSS max-height Property The max-height property in CSS is used to set the maximum height of an element. If the content of the element is larger than the specified maximum-height then the content will overflow otherwise it has no effect. If the content of the element is smaller then it has no effect. The height property val 3 min read
- How to set Line Height in Percent using CSS? The line-height property in CSS is used to set the line height in percentage by using the line-height: percent; property. This percentage is calculated based on the element's font size, allowing for flexible spacing between lines of text relative to their size. Syntax line-height: percent;Example 1: 2 min read
- Primer CSS Responsive Container Padding Primer CSS is a free open-source CSS framework based on concepts that set the foundation for basic design components such as space, font, and color. Because of their systematic structure, these patterns are both stable and interoperable. Its CSS approach is informed by Object-Oriented CSS concepts, 3 min read
- Foundation CSS Responsive Embed Aspect Ratios Foundation CSS is an open-source & responsive front-end framework built by the ZURB foundation in September 2011, which makes it easy to design beautiful responsive websites, apps, and emails that look amazing & can be accessible to any device. The framework is built on SaaS-like bootstrap. 3 min read
- CSS Layout - Horizontal & Vertical Align The Layout in CSS is used to control the flow of element inside another element. It sets the position of element in the web page. The position of element can be set by using horizontal and vertical alignment. There are many ways to set the position of element which are listed below: Using Position P 4 min read
- How to hide elements in responsive layout using CSS ? CSS provides powerful tools to create responsive websites that adapt to different screen sizes and devices. One of the key techniques for creating responsive designs is media queries, introduced in CSS3. Media queries allow you to apply styles based on the characteristics of the device, such as its 3 min read
- How to specify a division element should be resizable in CSS ? In this article, we will learn how to specify that a division element should be resizable by the user using CSS. Approach: The resize property is used to define if an element is resizable by the user. It can be specified with three values to denote that an element is resizable, that is, horizontal, 2 min read
- How to Set Viewport Height & Width in CSS ? Set viewport height and width in CSS is essential for creating responsive and visually appealing web designs. We'll explore the concepts of setting viewport height and width by using various methods like CSS Units, Viewport-Relative Units, and keyframe Media Queries. Table of Content Setting viewpor 3 min read
- How to Maintain the Aspect Ratio of an Element using CSS? Maintaining the aspect ratio of an element ensures that the element retains its width-to-height proportion regardless of screen size or resizing. This is particularly useful for responsive web design, where you need images, videos, and other elements to scale correctly without distortion. There are 3 min read
- Explain the working of calc() function in CSS The calc() function in CSS allows for dynamic calculations within property values, combining different units and mathematical operations. It enhances flexibility and responsiveness in layouts by enabling precise control over dimensions and spacing. Working of calc() functionThe calc() function in CS 3 min read
- HTML DOM clientHeight Property The DOM clientHeight property is used to return the viewable height of an element in terms of the pixel. It includes the measurement of the width of padding but does not include the margin, border, and scrollbar property for the measurement of the element width. This property only returns the actual 2 min read
- How To Create a Responsive Table in CSS ? A responsive table in CSS automatically changes to fit any screen size. It stays easy to read on small screens, like phones, by scrolling or adjusting columns as needed. To make a responsive table in CSS, place it inside a <div> with overflow-x: auto;. This lets the table scroll sideways on sm 3 min read
- How to design a responsive Web Page in HTML ? In this article, we will learn how to design a responsive Web Page in HTML. Responsive web design (RWD) is a web development approach that creates dynamic changes to the appearance of a website, depending on the screen size and orientation of the device being used to view it. RWD can be obtained by 3 min read
- Resize image proportionally with CSS To resize an image proportionally with CSS, you can use the max-width property to ensure the image adjusts automatically to fit its container without stretching. The height: auto rule maintains the image’s aspect ratio, preventing distortion. Following are how we can resize the image proportionally 2 min read
- How to get the rendered height of an element ? To get the height of an element, there are five common methods in JavaScript. Lets see the differences between each and when they should be used. Only the last method gives the correct rendered height instead of the layout height. style.height jQuery( height, innerHeight, outerHeight ) clientHeight, 10 min read
- Geeks Premier League
- Geeks Premier League 2023
Improve your Coding Skills with Practice
What kind of Experience do you want to share?
Andrei’s Substack
Share this post.
On the (copy-)assignment operator
Introduction
In our codebase evolved over 18 years and counting, there were inconsistencies regarding the return type of the copy assignment operator.
void operator=(const T&);
const T& operator=(const T&);
T& operator=(const T&);
My knee-jerk reaction was to convert the first two versions to the canonical form T& operator=() .
The T& operator=() form has been the default and promoted for a long time; the CPP core guidelines [1] provide this rationale:
F.47: Return T& from assignment operators Reason The convention for operator overloads (especially on concrete types) is for operator=(const T&) to perform the assignment and then return (non- const ) *this . This ensures consistency with standard-library types and follows the principle of "do as the ints do." Note Historically there was some guidance to make the assignment operator return const T& . This was primarily to avoid code of the form (a = b) = c -- such code is not common enough to warrant violating consistency with standard types.
“do as the ints do”, we will come back to this rule of thumb later.
But what effect has the return type on the ability to perform assignments? What is the difference between the three forms?
Consider the following class. The constructors were added in order to monitor the behavior of the objects and enable the interoperability with the standard library.
struct Foo {
int bar;
Foo() {
cout << "Foo()\n";
Foo(int val) : bar(val) {
cout << "Foo(int)\n";
Foo(const Foo& other) : bar(other.bar) {
cout << "Foo(const Foo&)\n";
void operator=(const Foo& other) {
cout << "Foo::op=(const Foo&)\n";
bar = other.bar;
int main() {
Foo a{1};
Foo b = a, c;
The output of this program is:
In the output, from top to bottom we have:
a is initialized
b = a (copy constructor)
c default constructed
c = a (copy assignment)
The assignment operator works as expected in these cases. What about using the standard library? Assume adding the following code to the main() function.
Foo value{1};
vector<Foo> v;
v.push_back(value);
value = v.back();
map<int, Foo> m;
m[1] = value;
value = m[1];
Once again, the code works - compiled with clang, gcc, msvc and intel cc.
Is there a case that does not work?
Any expression that requires the return value of the operator. E.g.
will result in a compiler error, such as:
In this example, the assignment c = a is processed first and the result is of type void . This type is incompatible with the assignment operator found for b, resulting in the error message. Returning anything compatible with Foo would result in a successful compilation.
Observation 1 : the non-void forms of the assignment operator enable bad practice. Once more quoting from the core guidelines:
ES.40: Avoid complicated expressions Reason Complicated expressions are error-prone. Example // bad: assignment hidden in subexpression while ((c = getc()) != -1) …
Note: projects that target functional safety certification or that have stricter coding standards i.e., use either MISRA-C++, Autosar C++ or similar guidelines, will disallow assignment operators in sub-expressions. The enforcement of such rules is left to the static code analysis tools.
Given the canonical form of the operator, what effect does it have on the copy elision on function return?
Consider the following changes to the code:
Foo& operator=(const Foo& other) {
return *this;
Foo test_nrvo() {
Foo a{1};
return c = a;
test_nrvo();
This code generates the following output, even with -O2 optimization level:
The last line in the output is a copy constructor called to initialize the temporary value returned by test_nrvo() .
If test_nrvo() in implemented in this form
return c;
the following output is generated:
The copy constructor is now missing, since copy elision was possible in this case. The same output was obtained from the binaries resulting from all four compilers previously enumerated.
Note: the void operator=() form cannot be used to write the return c = a; statement, as it would result in a compilation error.
Observation 2 : the void return type for the assignment operator has the benefit that code using it will not accidentally negatively-impact the performance and size of the resulting binary.
The current canonical form of the assignment operators is sub-optimal and allows writing subpar code that conflicts with other C++ core guidelines.
Unfortunately, the default copy assignment operator will use the canonical form. This behavior cannot be overwritten with the “ = default ” syntax. The defaulted operator must have the T& operator=(const T&) signature.
All assignment operators, including the compound assignment operators, should have the void return type.
As argued in Observation 1 & 2, the void return type form of the assignment operator has only benefits. It is unlikely that such a breaking change would find its way in the C++ standard.
The “do as the ints do” rule of thumb can be traced to Alexander Stepanov’s observation that types can be grouped in (algebraic) categories and depending on the category, certain algorithms would work correctly on corresponding objects. His focus was on fundamental operations and type properties, not on programming language gimmicks. Any software engineer - especially one that programs in C++ - should read and understand the “Elements of programming” book (ISBN 9780321635372) [2]
[1] C++ Core Guidelines https://github.com/isocpp/CppCoreGuidelines/
[2] Alexander Stepanov and Paul McJones, Elements of Programming, now available free of charge at http://elementsofprogramming.com/
[3] MISRA C++ https://misra.org.uk/publications/
[4] Autosar C++14 Guidelines https://www.autosar.org/fileadmin/standards/R22-11/AP/AUTOSAR_RS_CPP14Guidelines.pdf
Leave a comment
Discussion about this post
Ready for more?
IMAGES
COMMENTS
The standard correctly defines the return type of an assignment operator. Actually, the assignment operation itself doesn't depend on the return value - that's why the return type isn't straightforward to understanding. The return type is important for chaining operations. Consider the following construction: a = b = c;.
Aug 13, 2024 · To support this chaining, the assignment operator must return a reference to the object being assigned. This allows the operation b = c to return b, enabling a = b to work as expected. 2. Consistency with Built-in Types. For built-in types, the assignment operator in C++ returns a reference to the left-hand operand.
Jan 25, 2024 · All built-in assignment operators return * this, and most user-defined overloads also return * this so that the user-defined operators can be used in the same manner as the built-ins. However, in a user-defined operator overload, any type can be used as return type (including void ).
All built-in assignment operators return * this, and most user-defined overloads also return * this so that the user-defined operators can be used in the same manner as the built-ins. However, in a user-defined operator overload, any type can be used as return type (including void). T2 can be any type including T
Mar 1, 2024 · When the left operand is of an integral type, the right operand must not be of a pointer type. Result of built-in assignment operators. The built-in assignment operators return the value of the object specified by the left operand after the assignment (and the arithmetic/logical operation in the case of compound assignment operators).
Nov 15, 2023 · Compound Assignment Operators. In C++, the assignment operator can be combined into a single operator with some other operators to perform a combination of two operations in one single statement. These operators are called Compound Assignment Operators. There are 10 compound assignment operators in C++: Addition Assignment Operator ( += )
The return type is Box & and we eventually return *this. Here this is a pointer to the current instance (provided free of charge with every class). We return a reference, again to avoid an unnecessary copy operation. Why should the assignment operator return anything at all?
Aug 19, 2022 · Assignment performs implicit conversion from the value of rhs to the type of lhs and then replaces the value in the object designated by lhs with the converted value of rhs. Assignment also returns the same value as what was stored in lhs (so that expressions such as a = b = c are possible).
Sep 30, 2013 · Return type of assignment operator. Ask Question Asked 11 years, 2 months ago. Modified 3 years, 6 months ago. Viewed 737 times 18 When defining an assignment ...
Feb 6, 2024 · All assignment operators, including the compound assignment operators, should have the void return type. As argued in Observation 1 & 2, the void return type form of the assignment operator has only benefits. It is unlikely that such a breaking change would find its way in the C++ standard.