Library homepage

  • school Campus Bookshelves
  • menu_book Bookshelves
  • perm_media Learning Objects
  • login Login
  • how_to_reg Request Instructor Account
  • hub Instructor Commons

Margin Size

  • Download Page (PDF)
  • Download Full Book (PDF)
  • Periodic Table
  • Physics Constants
  • Scientific Calculator
  • Reference & Cite
  • Tools expand_more
  • Readability

selected template will load here

This action is not available.

Engineering LibreTexts

4.6: Assignment Operator

  • Last updated
  • Save as PDF
  • Page ID 29038

  • Patrick McClanahan
  • San Joaquin Delta College

\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

\( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)

( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)

\( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

\( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)

\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

\( \newcommand{\Span}{\mathrm{span}}\)

\( \newcommand{\id}{\mathrm{id}}\)

\( \newcommand{\kernel}{\mathrm{null}\,}\)

\( \newcommand{\range}{\mathrm{range}\,}\)

\( \newcommand{\RealPart}{\mathrm{Re}}\)

\( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

\( \newcommand{\Argument}{\mathrm{Arg}}\)

\( \newcommand{\norm}[1]{\| #1 \|}\)

\( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)

\( \newcommand{\vectorA}[1]{\vec{#1}}      % arrow\)

\( \newcommand{\vectorAt}[1]{\vec{\text{#1}}}      % arrow\)

\( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

\( \newcommand{\vectorC}[1]{\textbf{#1}} \)

\( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)

\( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)

\( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)

Assignment Operator

The assignment operator allows us to change the value of a modifiable data object (for beginning programmers this typically means a variable). It is associated with the concept of moving a value into the storage location (again usually a variable). Within C++ programming language the symbol used is the equal symbol. But bite your tongue, when you see the = symbol you need to start thinking: assignment. The assignment operator has two operands. The one to the left of the operator is usually an identifier name for a variable. The one to the right of the operator is a value.

The value 21 is moved to the memory location for the variable named: age. Another way to say it: age is assigned the value 21.

The item to the right of the assignment operator is an expression. The expression will be evaluated and the answer is 14. The value 14 would assigned to the variable named: total_cousins.

The expression to the right of the assignment operator contains some identifier names. The program would fetch the values stored in those variables; add them together and get a value of 44; then assign the 44 to the total_students variable.

As we have seen, assignment operators are used to assigning value to a variable. The left side operand of the assignment operator is a variable and right side operand of the assignment operator is a value. The value on the right side must be of the same data-type of the variable on the left side otherwise the compiler will raise an error. Different types of assignment operators are shown below:

  • “=” : This is the simplest assignment operator, which was discussed above. This operator is used to assign the value on the right to the variable on the left. For example: a = 10; b = 20; ch = 'y';

If initially the value 5 is stored in the variable a,  then:  (a += 6) is equal to 11.  (the same as: a = a + 6)

If initially value 8 is stored in the variable a, then (a -= 6) is equal to  2. (the same as a = a - 6)

If initially value 5 is stored in the variable a,, then (a *= 6) is equal to 30. (the same as a = a * 6)

If initially value 6 is stored in the variable a, then (a /= 2) is equal to 3. (the same as a = a / 2)

Below example illustrates the various Assignment Operators:

Definitions

 Adapted from:  "Assignment Operator"  by  Kenneth Leroy Busbee , (Download for free at http://cnx.org/contents/[email protected] ) is licensed under  CC BY 4.0

CProgramming Tutorial

  • C Programming Tutorial
  • C - Overview
  • C - Features
  • C - History
  • C - Environment Setup
  • C - Program Structure
  • C - Hello World
  • C - Compilation Process
  • C - Comments
  • C - Keywords
  • C - Identifiers
  • C - User Input
  • C - Basic Syntax
  • C - Data Types
  • C - Variables
  • C - Integer Promotions
  • C - Type Conversion
  • C - Booleans
  • C - Constants
  • C - Literals
  • C - Escape sequences
  • C - Format Specifiers
  • C - Storage Classes
  • C - Operators
  • C - Arithmetic Operators
  • C - Relational Operators
  • C - Logical Operators
  • C - Bitwise Operators
  • C - Assignment Operators
  • C - Unary Operators
  • C - Increment and Decrement Operators
  • C - Ternary Operator
  • C - sizeof Operator
  • C - Operator Precedence
  • C - Misc Operators
  • C - Decision Making
  • C - if statement
  • C - if...else statement
  • C - nested if statements
  • C - switch statement
  • C - nested switch statements
  • C - While loop
  • C - For loop
  • C - Do...while loop
  • C - Nested loop
  • C - Infinite loop
  • C - Break Statement
  • C - Continue Statement
  • C - goto Statement
  • C - Functions
  • C - Main Functions
  • C - Function call by Value
  • C - Function call by reference
  • C - Nested Functions
  • C - Variadic Functions
  • C - User-Defined Functions
  • C - Callback Function
  • C - Return Statement
  • C - Recursion
  • C - Scope Rules
  • C - Static Variables
  • C - Global Variables
  • C - Properties of Array
  • C - Multi-Dimensional Arrays
  • C - Passing Arrays to Function
  • C - Return Array from Function
  • C - Variable Length Arrays
  • C - Pointers
  • C - Pointers and Arrays
  • C - Applications of Pointers
  • C - Pointer Arithmetics
  • C - Array of Pointers
  • C - Passing Pointers to Functions
  • C - Strings
  • C - Array of Strings
  • C - Structures
  • C - Structures and Functions
  • C - Arrays of Structures
  • C - Pointers to Structures
  • C - Self-Referential Structures
  • C - Nested Structures
  • C - Bit Fields
  • C - Typedef
  • C - Input & Output
  • C - File I/O
  • C - Preprocessors
  • C - Header Files
  • C - Type Casting
  • C - Error Handling
  • C - Variable Arguments
  • C - Memory Management
  • C - Command Line Arguments
  • C Programming Resources
  • C - Questions & Answers
  • C - Quick Guide
  • C - Useful Resources
  • C - Discussion
  • Selected Reading
  • UPSC IAS Exams Notes
  • Developer's Best Practices
  • Questions and Answers
  • Effective Resume Writing
  • HR Interview Questions
  • Computer Glossary

Assignment Operators in C

In C language, the assignment operator stores a certain value in an already declared variable. A variable in C can be assigned the value in the form of a literal, another variable, or an expression.

The value to be assigned forms the right-hand operand, whereas the variable to be assigned should be the operand to the left of the " = " symbol, which is defined as a simple assignment operator in C.

In addition, C has several augmented assignment operators.

The following table lists the assignment operators supported by the C language −

Simple Assignment Operator (=)

The = operator is one of the most frequently used operators in C. As per the ANSI C standard, all the variables must be declared in the beginning. Variable declaration after the first processing statement is not allowed.

You can declare a variable to be assigned a value later in the code, or you can initialize it at the time of declaration.

You can use a literal, another variable, or an expression in the assignment statement.

Once a variable of a certain type is declared, it cannot be assigned a value of any other type. In such a case the C compiler reports a type mismatch error.

In C, the expressions that refer to a memory location are called "lvalue" expressions. A lvalue may appear as either the left-hand or right-hand side of an assignment.

On the other hand, the term rvalue refers to a data value that is stored at some address in memory. A rvalue is an expression that cannot have a value assigned to it which means an rvalue may appear on the right-hand side but not on the left-hand side of an assignment.

Variables are lvalues and so they may appear on the left-hand side of an assignment. Numeric literals are rvalues and so they may not be assigned and cannot appear on the left-hand side. Take a look at the following valid and invalid statements −

Augmented Assignment Operators

In addition to the = operator, C allows you to combine arithmetic and bitwise operators with the = symbol to form augmented or compound assignment operator. The augmented operators offer a convenient shortcut for combining arithmetic or bitwise operation with assignment.

For example, the expression "a += b" has the same effect of performing "a + b" first and then assigning the result back to the variable "a".

Run the code and check its output −

Similarly, the expression "a <<= b" has the same effect of performing "a << b" first and then assigning the result back to the variable "a".

Here is a C program that demonstrates the use of assignment operators in C −

When you compile and execute the above program, it will produce the following result −

To Continue Learning Please Login

Python Enhancement Proposals

  • Python »
  • PEP Index »

PEP 572 – Assignment Expressions

The importance of real code, exceptional cases, scope of the target, relative precedence of :=, change to evaluation order, differences between assignment expressions and assignment statements, specification changes during implementation, _pydecimal.py, datetime.py, sysconfig.py, simplifying list comprehensions, capturing condition values, changing the scope rules for comprehensions, alternative spellings, special-casing conditional statements, special-casing comprehensions, lowering operator precedence, allowing commas to the right, always requiring parentheses, why not just turn existing assignment into an expression, with assignment expressions, why bother with assignment statements, why not use a sublocal scope and prevent namespace pollution, style guide recommendations, acknowledgements, a numeric example, appendix b: rough code translations for comprehensions, appendix c: no changes to scope semantics.

This is a proposal for creating a way to assign to variables within an expression using the notation NAME := expr .

As part of this change, there is also an update to dictionary comprehension evaluation order to ensure key expressions are executed before value expressions (allowing the key to be bound to a name and then re-used as part of calculating the corresponding value).

During discussion of this PEP, the operator became informally known as “the walrus operator”. The construct’s formal name is “Assignment Expressions” (as per the PEP title), but they may also be referred to as “Named Expressions” (e.g. the CPython reference implementation uses that name internally).

Naming the result of an expression is an important part of programming, allowing a descriptive name to be used in place of a longer expression, and permitting reuse. Currently, this feature is available only in statement form, making it unavailable in list comprehensions and other expression contexts.

Additionally, naming sub-parts of a large expression can assist an interactive debugger, providing useful display hooks and partial results. Without a way to capture sub-expressions inline, this would require refactoring of the original code; with assignment expressions, this merely requires the insertion of a few name := markers. Removing the need to refactor reduces the likelihood that the code be inadvertently changed as part of debugging (a common cause of Heisenbugs), and is easier to dictate to another programmer.

During the development of this PEP many people (supporters and critics both) have had a tendency to focus on toy examples on the one hand, and on overly complex examples on the other.

The danger of toy examples is twofold: they are often too abstract to make anyone go “ooh, that’s compelling”, and they are easily refuted with “I would never write it that way anyway”.

The danger of overly complex examples is that they provide a convenient strawman for critics of the proposal to shoot down (“that’s obfuscated”).

Yet there is some use for both extremely simple and extremely complex examples: they are helpful to clarify the intended semantics. Therefore, there will be some of each below.

However, in order to be compelling , examples should be rooted in real code, i.e. code that was written without any thought of this PEP, as part of a useful application, however large or small. Tim Peters has been extremely helpful by going over his own personal code repository and picking examples of code he had written that (in his view) would have been clearer if rewritten with (sparing) use of assignment expressions. His conclusion: the current proposal would have allowed a modest but clear improvement in quite a few bits of code.

Another use of real code is to observe indirectly how much value programmers place on compactness. Guido van Rossum searched through a Dropbox code base and discovered some evidence that programmers value writing fewer lines over shorter lines.

Case in point: Guido found several examples where a programmer repeated a subexpression, slowing down the program, in order to save one line of code, e.g. instead of writing:

they would write:

Another example illustrates that programmers sometimes do more work to save an extra level of indentation:

This code tries to match pattern2 even if pattern1 has a match (in which case the match on pattern2 is never used). The more efficient rewrite would have been:

Syntax and semantics

In most contexts where arbitrary Python expressions can be used, a named expression can appear. This is of the form NAME := expr where expr is any valid Python expression other than an unparenthesized tuple, and NAME is an identifier.

The value of such a named expression is the same as the incorporated expression, with the additional side-effect that the target is assigned that value:

There are a few places where assignment expressions are not allowed, in order to avoid ambiguities or user confusion:

This rule is included to simplify the choice for the user between an assignment statement and an assignment expression – there is no syntactic position where both are valid.

Again, this rule is included to avoid two visually similar ways of saying the same thing.

This rule is included to disallow excessively confusing code, and because parsing keyword arguments is complex enough already.

This rule is included to discourage side effects in a position whose exact semantics are already confusing to many users (cf. the common style recommendation against mutable default values), and also to echo the similar prohibition in calls (the previous bullet).

The reasoning here is similar to the two previous cases; this ungrouped assortment of symbols and operators composed of : and = is hard to read correctly.

This allows lambda to always bind less tightly than := ; having a name binding at the top level inside a lambda function is unlikely to be of value, as there is no way to make use of it. In cases where the name will be used more than once, the expression is likely to need parenthesizing anyway, so this prohibition will rarely affect code.

This shows that what looks like an assignment operator in an f-string is not always an assignment operator. The f-string parser uses : to indicate formatting options. To preserve backwards compatibility, assignment operator usage inside of f-strings must be parenthesized. As noted above, this usage of the assignment operator is not recommended.

An assignment expression does not introduce a new scope. In most cases the scope in which the target will be bound is self-explanatory: it is the current scope. If this scope contains a nonlocal or global declaration for the target, the assignment expression honors that. A lambda (being an explicit, if anonymous, function definition) counts as a scope for this purpose.

There is one special case: an assignment expression occurring in a list, set or dict comprehension or in a generator expression (below collectively referred to as “comprehensions”) binds the target in the containing scope, honoring a nonlocal or global declaration for the target in that scope, if one exists. For the purpose of this rule the containing scope of a nested comprehension is the scope that contains the outermost comprehension. A lambda counts as a containing scope.

The motivation for this special case is twofold. First, it allows us to conveniently capture a “witness” for an any() expression, or a counterexample for all() , for example:

Second, it allows a compact way of updating mutable state from a comprehension, for example:

However, an assignment expression target name cannot be the same as a for -target name appearing in any comprehension containing the assignment expression. The latter names are local to the comprehension in which they appear, so it would be contradictory for a contained use of the same name to refer to the scope containing the outermost comprehension instead.

For example, [i := i+1 for i in range(5)] is invalid: the for i part establishes that i is local to the comprehension, but the i := part insists that i is not local to the comprehension. The same reason makes these examples invalid too:

While it’s technically possible to assign consistent semantics to these cases, it’s difficult to determine whether those semantics actually make sense in the absence of real use cases. Accordingly, the reference implementation [1] will ensure that such cases raise SyntaxError , rather than executing with implementation defined behaviour.

This restriction applies even if the assignment expression is never executed:

For the comprehension body (the part before the first “for” keyword) and the filter expression (the part after “if” and before any nested “for”), this restriction applies solely to target names that are also used as iteration variables in the comprehension. Lambda expressions appearing in these positions introduce a new explicit function scope, and hence may use assignment expressions with no additional restrictions.

Due to design constraints in the reference implementation (the symbol table analyser cannot easily detect when names are re-used between the leftmost comprehension iterable expression and the rest of the comprehension), named expressions are disallowed entirely as part of comprehension iterable expressions (the part after each “in”, and before any subsequent “if” or “for” keyword):

A further exception applies when an assignment expression occurs in a comprehension whose containing scope is a class scope. If the rules above were to result in the target being assigned in that class’s scope, the assignment expression is expressly invalid. This case also raises SyntaxError :

(The reason for the latter exception is the implicit function scope created for comprehensions – there is currently no runtime mechanism for a function to refer to a variable in the containing class scope, and we do not want to add such a mechanism. If this issue ever gets resolved this special case may be removed from the specification of assignment expressions. Note that the problem already exists for using a variable defined in the class scope from a comprehension.)

See Appendix B for some examples of how the rules for targets in comprehensions translate to equivalent code.

The := operator groups more tightly than a comma in all syntactic positions where it is legal, but less tightly than all other operators, including or , and , not , and conditional expressions ( A if C else B ). As follows from section “Exceptional cases” above, it is never allowed at the same level as = . In case a different grouping is desired, parentheses should be used.

The := operator may be used directly in a positional function call argument; however it is invalid directly in a keyword argument.

Some examples to clarify what’s technically valid or invalid:

Most of the “valid” examples above are not recommended, since human readers of Python source code who are quickly glancing at some code may miss the distinction. But simple cases are not objectionable:

This PEP recommends always putting spaces around := , similar to PEP 8 ’s recommendation for = when used for assignment, whereas the latter disallows spaces around = used for keyword arguments.)

In order to have precisely defined semantics, the proposal requires evaluation order to be well-defined. This is technically not a new requirement, as function calls may already have side effects. Python already has a rule that subexpressions are generally evaluated from left to right. However, assignment expressions make these side effects more visible, and we propose a single change to the current evaluation order:

  • In a dict comprehension {X: Y for ...} , Y is currently evaluated before X . We propose to change this so that X is evaluated before Y . (In a dict display like {X: Y} this is already the case, and also in dict((X, Y) for ...) which should clearly be equivalent to the dict comprehension.)

Most importantly, since := is an expression, it can be used in contexts where statements are illegal, including lambda functions and comprehensions.

Conversely, assignment expressions don’t support the advanced features found in assignment statements:

  • Multiple targets are not directly supported: x = y = z = 0 # Equivalent: (z := (y := (x := 0)))
  • Single assignment targets other than a single NAME are not supported: # No equivalent a [ i ] = x self . rest = []
  • Priority around commas is different: x = 1 , 2 # Sets x to (1, 2) ( x := 1 , 2 ) # Sets x to 1
  • Iterable packing and unpacking (both regular or extended forms) are not supported: # Equivalent needs extra parentheses loc = x , y # Use (loc := (x, y)) info = name , phone , * rest # Use (info := (name, phone, *rest)) # No equivalent px , py , pz = position name , phone , email , * other_info = contact
  • Inline type annotations are not supported: # Closest equivalent is "p: Optional[int]" as a separate declaration p : Optional [ int ] = None
  • Augmented assignment is not supported: total += tax # Equivalent: (total := total + tax)

The following changes have been made based on implementation experience and additional review after the PEP was first accepted and before Python 3.8 was released:

  • for consistency with other similar exceptions, and to avoid locking in an exception name that is not necessarily going to improve clarity for end users, the originally proposed TargetScopeError subclass of SyntaxError was dropped in favour of just raising SyntaxError directly. [3]
  • due to a limitation in CPython’s symbol table analysis process, the reference implementation raises SyntaxError for all uses of named expressions inside comprehension iterable expressions, rather than only raising them when the named expression target conflicts with one of the iteration variables in the comprehension. This could be revisited given sufficiently compelling examples, but the extra complexity needed to implement the more selective restriction doesn’t seem worthwhile for purely hypothetical use cases.

Examples from the Python standard library

env_base is only used on these lines, putting its assignment on the if moves it as the “header” of the block.

  • Current: env_base = os . environ . get ( "PYTHONUSERBASE" , None ) if env_base : return env_base
  • Improved: if env_base := os . environ . get ( "PYTHONUSERBASE" , None ): return env_base

Avoid nested if and remove one indentation level.

  • Current: if self . _is_special : ans = self . _check_nans ( context = context ) if ans : return ans
  • Improved: if self . _is_special and ( ans := self . _check_nans ( context = context )): return ans

Code looks more regular and avoid multiple nested if. (See Appendix A for the origin of this example.)

  • Current: reductor = dispatch_table . get ( cls ) if reductor : rv = reductor ( x ) else : reductor = getattr ( x , "__reduce_ex__" , None ) if reductor : rv = reductor ( 4 ) else : reductor = getattr ( x , "__reduce__" , None ) if reductor : rv = reductor () else : raise Error ( "un(deep)copyable object of type %s " % cls )
  • Improved: if reductor := dispatch_table . get ( cls ): rv = reductor ( x ) elif reductor := getattr ( x , "__reduce_ex__" , None ): rv = reductor ( 4 ) elif reductor := getattr ( x , "__reduce__" , None ): rv = reductor () else : raise Error ( "un(deep)copyable object of type %s " % cls )

tz is only used for s += tz , moving its assignment inside the if helps to show its scope.

  • Current: s = _format_time ( self . _hour , self . _minute , self . _second , self . _microsecond , timespec ) tz = self . _tzstr () if tz : s += tz return s
  • Improved: s = _format_time ( self . _hour , self . _minute , self . _second , self . _microsecond , timespec ) if tz := self . _tzstr (): s += tz return s

Calling fp.readline() in the while condition and calling .match() on the if lines make the code more compact without making it harder to understand.

  • Current: while True : line = fp . readline () if not line : break m = define_rx . match ( line ) if m : n , v = m . group ( 1 , 2 ) try : v = int ( v ) except ValueError : pass vars [ n ] = v else : m = undef_rx . match ( line ) if m : vars [ m . group ( 1 )] = 0
  • Improved: while line := fp . readline (): if m := define_rx . match ( line ): n , v = m . group ( 1 , 2 ) try : v = int ( v ) except ValueError : pass vars [ n ] = v elif m := undef_rx . match ( line ): vars [ m . group ( 1 )] = 0

A list comprehension can map and filter efficiently by capturing the condition:

Similarly, a subexpression can be reused within the main expression, by giving it a name on first use:

Note that in both cases the variable y is bound in the containing scope (i.e. at the same level as results or stuff ).

Assignment expressions can be used to good effect in the header of an if or while statement:

Particularly with the while loop, this can remove the need to have an infinite loop, an assignment, and a condition. It also creates a smooth parallel between a loop which simply uses a function call as its condition, and one which uses that as its condition but also uses the actual value.

An example from the low-level UNIX world:

Rejected alternative proposals

Proposals broadly similar to this one have come up frequently on python-ideas. Below are a number of alternative syntaxes, some of them specific to comprehensions, which have been rejected in favour of the one given above.

A previous version of this PEP proposed subtle changes to the scope rules for comprehensions, to make them more usable in class scope and to unify the scope of the “outermost iterable” and the rest of the comprehension. However, this part of the proposal would have caused backwards incompatibilities, and has been withdrawn so the PEP can focus on assignment expressions.

Broadly the same semantics as the current proposal, but spelled differently.

Since EXPR as NAME already has meaning in import , except and with statements (with different semantics), this would create unnecessary confusion or require special-casing (e.g. to forbid assignment within the headers of these statements).

(Note that with EXPR as VAR does not simply assign the value of EXPR to VAR – it calls EXPR.__enter__() and assigns the result of that to VAR .)

Additional reasons to prefer := over this spelling include:

  • In if f(x) as y the assignment target doesn’t jump out at you – it just reads like if f x blah blah and it is too similar visually to if f(x) and y .
  • import foo as bar
  • except Exc as var
  • with ctxmgr() as var

To the contrary, the assignment expression does not belong to the if or while that starts the line, and we intentionally allow assignment expressions in other contexts as well.

  • NAME = EXPR
  • if NAME := EXPR

reinforces the visual recognition of assignment expressions.

This syntax is inspired by languages such as R and Haskell, and some programmable calculators. (Note that a left-facing arrow y <- f(x) is not possible in Python, as it would be interpreted as less-than and unary minus.) This syntax has a slight advantage over ‘as’ in that it does not conflict with with , except and import , but otherwise is equivalent. But it is entirely unrelated to Python’s other use of -> (function return type annotations), and compared to := (which dates back to Algol-58) it has a much weaker tradition.

This has the advantage that leaked usage can be readily detected, removing some forms of syntactic ambiguity. However, this would be the only place in Python where a variable’s scope is encoded into its name, making refactoring harder.

Execution order is inverted (the indented body is performed first, followed by the “header”). This requires a new keyword, unless an existing keyword is repurposed (most likely with: ). See PEP 3150 for prior discussion on this subject (with the proposed keyword being given: ).

This syntax has fewer conflicts than as does (conflicting only with the raise Exc from Exc notation), but is otherwise comparable to it. Instead of paralleling with expr as target: (which can be useful but can also be confusing), this has no parallels, but is evocative.

One of the most popular use-cases is if and while statements. Instead of a more general solution, this proposal enhances the syntax of these two statements to add a means of capturing the compared value:

This works beautifully if and ONLY if the desired condition is based on the truthiness of the captured value. It is thus effective for specific use-cases (regex matches, socket reads that return '' when done), and completely useless in more complicated cases (e.g. where the condition is f(x) < 0 and you want to capture the value of f(x) ). It also has no benefit to list comprehensions.

Advantages: No syntactic ambiguities. Disadvantages: Answers only a fraction of possible use-cases, even in if / while statements.

Another common use-case is comprehensions (list/set/dict, and genexps). As above, proposals have been made for comprehension-specific solutions.

This brings the subexpression to a location in between the ‘for’ loop and the expression. It introduces an additional language keyword, which creates conflicts. Of the three, where reads the most cleanly, but also has the greatest potential for conflict (e.g. SQLAlchemy and numpy have where methods, as does tkinter.dnd.Icon in the standard library).

As above, but reusing the with keyword. Doesn’t read too badly, and needs no additional language keyword. Is restricted to comprehensions, though, and cannot as easily be transformed into “longhand” for-loop syntax. Has the C problem that an equals sign in an expression can now create a name binding, rather than performing a comparison. Would raise the question of why “with NAME = EXPR:” cannot be used as a statement on its own.

As per option 2, but using as rather than an equals sign. Aligns syntactically with other uses of as for name binding, but a simple transformation to for-loop longhand would create drastically different semantics; the meaning of with inside a comprehension would be completely different from the meaning as a stand-alone statement, while retaining identical syntax.

Regardless of the spelling chosen, this introduces a stark difference between comprehensions and the equivalent unrolled long-hand form of the loop. It is no longer possible to unwrap the loop into statement form without reworking any name bindings. The only keyword that can be repurposed to this task is with , thus giving it sneakily different semantics in a comprehension than in a statement; alternatively, a new keyword is needed, with all the costs therein.

There are two logical precedences for the := operator. Either it should bind as loosely as possible, as does statement-assignment; or it should bind more tightly than comparison operators. Placing its precedence between the comparison and arithmetic operators (to be precise: just lower than bitwise OR) allows most uses inside while and if conditions to be spelled without parentheses, as it is most likely that you wish to capture the value of something, then perform a comparison on it:

Once find() returns -1, the loop terminates. If := binds as loosely as = does, this would capture the result of the comparison (generally either True or False ), which is less useful.

While this behaviour would be convenient in many situations, it is also harder to explain than “the := operator behaves just like the assignment statement”, and as such, the precedence for := has been made as close as possible to that of = (with the exception that it binds tighter than comma).

Some critics have claimed that the assignment expressions should allow unparenthesized tuples on the right, so that these two would be equivalent:

(With the current version of the proposal, the latter would be equivalent to ((point := x), y) .)

However, adopting this stance would logically lead to the conclusion that when used in a function call, assignment expressions also bind less tight than comma, so we’d have the following confusing equivalence:

The less confusing option is to make := bind more tightly than comma.

It’s been proposed to just always require parentheses around an assignment expression. This would resolve many ambiguities, and indeed parentheses will frequently be needed to extract the desired subexpression. But in the following cases the extra parentheses feel redundant:

Frequently Raised Objections

C and its derivatives define the = operator as an expression, rather than a statement as is Python’s way. This allows assignments in more contexts, including contexts where comparisons are more common. The syntactic similarity between if (x == y) and if (x = y) belies their drastically different semantics. Thus this proposal uses := to clarify the distinction.

The two forms have different flexibilities. The := operator can be used inside a larger expression; the = statement can be augmented to += and its friends, can be chained, and can assign to attributes and subscripts.

Previous revisions of this proposal involved sublocal scope (restricted to a single statement), preventing name leakage and namespace pollution. While a definite advantage in a number of situations, this increases complexity in many others, and the costs are not justified by the benefits. In the interests of language simplicity, the name bindings created here are exactly equivalent to any other name bindings, including that usage at class or module scope will create externally-visible names. This is no different from for loops or other constructs, and can be solved the same way: del the name once it is no longer needed, or prefix it with an underscore.

(The author wishes to thank Guido van Rossum and Christoph Groth for their suggestions to move the proposal in this direction. [2] )

As expression assignments can sometimes be used equivalently to statement assignments, the question of which should be preferred will arise. For the benefit of style guides such as PEP 8 , two recommendations are suggested.

  • If either assignment statements or assignment expressions can be used, prefer statements; they are a clear declaration of intent.
  • If using assignment expressions would lead to ambiguity about execution order, restructure it to use statements instead.

The authors wish to thank Alyssa Coghlan and Steven D’Aprano for their considerable contributions to this proposal, and members of the core-mentorship mailing list for assistance with implementation.

Appendix A: Tim Peters’s findings

Here’s a brief essay Tim Peters wrote on the topic.

I dislike “busy” lines of code, and also dislike putting conceptually unrelated logic on a single line. So, for example, instead of:

instead. So I suspected I’d find few places I’d want to use assignment expressions. I didn’t even consider them for lines already stretching halfway across the screen. In other cases, “unrelated” ruled:

is a vast improvement over the briefer:

The original two statements are doing entirely different conceptual things, and slamming them together is conceptually insane.

In other cases, combining related logic made it harder to understand, such as rewriting:

as the briefer:

The while test there is too subtle, crucially relying on strict left-to-right evaluation in a non-short-circuiting or method-chaining context. My brain isn’t wired that way.

But cases like that were rare. Name binding is very frequent, and “sparse is better than dense” does not mean “almost empty is better than sparse”. For example, I have many functions that return None or 0 to communicate “I have nothing useful to return in this case, but since that’s expected often I’m not going to annoy you with an exception”. This is essentially the same as regular expression search functions returning None when there is no match. So there was lots of code of the form:

I find that clearer, and certainly a bit less typing and pattern-matching reading, as:

It’s also nice to trade away a small amount of horizontal whitespace to get another _line_ of surrounding code on screen. I didn’t give much weight to this at first, but it was so very frequent it added up, and I soon enough became annoyed that I couldn’t actually run the briefer code. That surprised me!

There are other cases where assignment expressions really shine. Rather than pick another from my code, Kirill Balunov gave a lovely example from the standard library’s copy() function in copy.py :

The ever-increasing indentation is semantically misleading: the logic is conceptually flat, “the first test that succeeds wins”:

Using easy assignment expressions allows the visual structure of the code to emphasize the conceptual flatness of the logic; ever-increasing indentation obscured it.

A smaller example from my code delighted me, both allowing to put inherently related logic in a single line, and allowing to remove an annoying “artificial” indentation level:

That if is about as long as I want my lines to get, but remains easy to follow.

So, in all, in most lines binding a name, I wouldn’t use assignment expressions, but because that construct is so very frequent, that leaves many places I would. In most of the latter, I found a small win that adds up due to how often it occurs, and in the rest I found a moderate to major win. I’d certainly use it more often than ternary if , but significantly less often than augmented assignment.

I have another example that quite impressed me at the time.

Where all variables are positive integers, and a is at least as large as the n’th root of x, this algorithm returns the floor of the n’th root of x (and roughly doubling the number of accurate bits per iteration):

It’s not obvious why that works, but is no more obvious in the “loop and a half” form. It’s hard to prove correctness without building on the right insight (the “arithmetic mean - geometric mean inequality”), and knowing some non-trivial things about how nested floor functions behave. That is, the challenges are in the math, not really in the coding.

If you do know all that, then the assignment-expression form is easily read as “while the current guess is too large, get a smaller guess”, where the “too large?” test and the new guess share an expensive sub-expression.

To my eyes, the original form is harder to understand:

This appendix attempts to clarify (though not specify) the rules when a target occurs in a comprehension or in a generator expression. For a number of illustrative examples we show the original code, containing a comprehension, and the translation, where the comprehension has been replaced by an equivalent generator function plus some scaffolding.

Since [x for ...] is equivalent to list(x for ...) these examples all use list comprehensions without loss of generality. And since these examples are meant to clarify edge cases of the rules, they aren’t trying to look like real code.

Note: comprehensions are already implemented via synthesizing nested generator functions like those in this appendix. The new part is adding appropriate declarations to establish the intended scope of assignment expression targets (the same scope they resolve to as if the assignment were performed in the block containing the outermost comprehension). For type inference purposes, these illustrative expansions do not imply that assignment expression targets are always Optional (but they do indicate the target binding scope).

Let’s start with a reminder of what code is generated for a generator expression without assignment expression.

  • Original code (EXPR usually references VAR): def f (): a = [ EXPR for VAR in ITERABLE ]
  • Translation (let’s not worry about name conflicts): def f (): def genexpr ( iterator ): for VAR in iterator : yield EXPR a = list ( genexpr ( iter ( ITERABLE )))

Let’s add a simple assignment expression.

  • Original code: def f (): a = [ TARGET := EXPR for VAR in ITERABLE ]
  • Translation: def f (): if False : TARGET = None # Dead code to ensure TARGET is a local variable def genexpr ( iterator ): nonlocal TARGET for VAR in iterator : TARGET = EXPR yield TARGET a = list ( genexpr ( iter ( ITERABLE )))

Let’s add a global TARGET declaration in f() .

  • Original code: def f (): global TARGET a = [ TARGET := EXPR for VAR in ITERABLE ]
  • Translation: def f (): global TARGET def genexpr ( iterator ): global TARGET for VAR in iterator : TARGET = EXPR yield TARGET a = list ( genexpr ( iter ( ITERABLE )))

Or instead let’s add a nonlocal TARGET declaration in f() .

  • Original code: def g (): TARGET = ... def f (): nonlocal TARGET a = [ TARGET := EXPR for VAR in ITERABLE ]
  • Translation: def g (): TARGET = ... def f (): nonlocal TARGET def genexpr ( iterator ): nonlocal TARGET for VAR in iterator : TARGET = EXPR yield TARGET a = list ( genexpr ( iter ( ITERABLE )))

Finally, let’s nest two comprehensions.

  • Original code: def f (): a = [[ TARGET := i for i in range ( 3 )] for j in range ( 2 )] # I.e., a = [[0, 1, 2], [0, 1, 2]] print ( TARGET ) # prints 2
  • Translation: def f (): if False : TARGET = None def outer_genexpr ( outer_iterator ): nonlocal TARGET def inner_generator ( inner_iterator ): nonlocal TARGET for i in inner_iterator : TARGET = i yield i for j in outer_iterator : yield list ( inner_generator ( range ( 3 ))) a = list ( outer_genexpr ( range ( 2 ))) print ( TARGET )

Because it has been a point of confusion, note that nothing about Python’s scoping semantics is changed. Function-local scopes continue to be resolved at compile time, and to have indefinite temporal extent at run time (“full closures”). Example:

This document has been placed in the public domain.

Source: https://github.com/python/peps/blob/main/peps/pep-0572.rst

Last modified: 2023-10-11 12:05:51 GMT

The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available. See Java Language Changes for a summary of updated language features in Java SE 9 and subsequent releases. See JDK Release Notes for information about new features, enhancements, and removed or deprecated options for all JDK releases.

Assignment, Arithmetic, and Unary Operators

The simple assignment operator.

One of the most common operators that you'll encounter is the simple assignment operator " = ". You saw this operator in the Bicycle class; it assigns the value on its right to the operand on its left:

This operator can also be used on objects to assign object references , as discussed in Creating Objects .

The Arithmetic Operators

The Java programming language provides operators that perform addition, subtraction, multiplication, and division. There's a good chance you'll recognize them by their counterparts in basic mathematics. The only symbol that might look new to you is " % ", which divides one operand by another and returns the remainder as its result.

The following program, ArithmeticDemo , tests the arithmetic operators.

This program prints the following:

You can also combine the arithmetic operators with the simple assignment operator to create compound assignments . For example, x+=1; and x=x+1; both increment the value of x by 1.

The + operator can also be used for concatenating (joining) two strings together, as shown in the following ConcatDemo program:

By the end of this program, the variable thirdString contains "This is a concatenated string.", which gets printed to standard output.

The Unary Operators

The unary operators require only one operand; they perform various operations such as incrementing/decrementing a value by one, negating an expression, or inverting the value of a boolean.

The following program, UnaryDemo , tests the unary operators:

The increment/decrement operators can be applied before (prefix) or after (postfix) the operand. The code result++; and ++result; will both end in result being incremented by one. The only difference is that the prefix version ( ++result ) evaluates to the incremented value, whereas the postfix version ( result++ ) evaluates to the original value. If you are just performing a simple increment/decrement, it doesn't really matter which version you choose. But if you use this operator in part of a larger expression, the one that you choose may make a significant difference.

The following program, PrePostDemo , illustrates the prefix/postfix unary increment operator:

About Oracle | Contact Us | Legal Notices | Terms of Use | Your Privacy Rights

Copyright © 1995, 2022 Oracle and/or its affiliates. All rights reserved.

Assignment operators

Assignment operators modify the value of the object.

Explanation

copy assignment operator replaces the contents of the object a with a copy of the contents of b ( b is not modified). For class types, this is a special member function, described in copy assignment operator .

move assignment operator replaces the contents of the object a with the contents of b , avoiding copying if possible ( b may be modified). For class types, this is a special member function, described in move assignment operator . (since C++11)

For non-class types, copy and move assignment are indistinguishable and are referred to as direct assignment .

compound assignment operators replace the contents of the object a with the result of a binary operation between the previous value of a and the value of b .

Builtin direct assignment

The direct assignment expressions have the form

For the built-in operator, lhs may have any non-const scalar type and rhs must be implicitly convertible to the type of lhs .

The direct assignment operator expects a modifiable lvalue as its left operand and an rvalue expression or a braced-init-list (since C++11) as its right operand, and returns an lvalue identifying the left operand after modification.

For non-class types, the right operand is first implicitly converted to the cv-unqualified type of the left operand, and then its value is copied into the object identified by left operand.

When the left operand has reference type, the assignment operator modifies the referred-to object.

If the left and the right operands identify overlapping objects, the behavior is undefined (unless the overlap is exact and the type is the same)

In overload resolution against user-defined operators , for every type T , the following function signatures participate in overload resolution:

For every enumeration or pointer to member type T , optionally volatile-qualified, the following function signature participates in overload resolution:

For every pair A1 and A2, where A1 is an arithmetic type (optionally volatile-qualified) and A2 is a promoted arithmetic type, the following function signature participates in overload resolution:

Builtin compound assignment

The compound assignment expressions have the form

The behavior of every builtin compound-assignment expression E1 op = E2 (where E1 is a modifiable lvalue expression and E2 is an rvalue expression or a braced-init-list (since C++11) ) is exactly the same as the behavior of the expression E1 = E1 op E2 , except that the expression E1 is evaluated only once and that it behaves as a single operation with respect to indeterminately-sequenced function calls (e.g. in f ( a + = b, g ( ) ) , the += is either not started at all or is completed as seen from inside g ( ) ).

In overload resolution against user-defined operators , for every pair A1 and A2, where A1 is an arithmetic type (optionally volatile-qualified) and A2 is a promoted arithmetic type, the following function signatures participate in overload resolution:

For every pair I1 and I2, where I1 is an integral type (optionally volatile-qualified) and I2 is a promoted integral type, the following function signatures participate in overload resolution:

For every optionally cv-qualified object type T , the following function signatures participate in overload resolution:

Operator precedence

Operator overloading

  • Skip to main content
  • Skip to search
  • Skip to select language
  • Sign up for free
  • Português (do Brasil)

Operator precedence

Operator precedence determines how operators are parsed concerning each other. Operators with higher precedence become the operands of operators with lower precedence.

Precedence and associativity

Consider an expression describable by the representation below, where both OP1 and OP2 are fill-in-the-blanks for OPerators.

The combination above has two possible interpretations:

Which one the language decides to adopt depends on the identity of OP1 and OP2 .

If OP1 and OP2 have different precedence levels (see the table below), the operator with the higher precedence goes first and associativity does not matter. Observe how multiplication has higher precedence than addition and executed first, even though addition is written first in the code.

Within operators of the same precedence, the language groups them by associativity . Left-associativity (left-to-right) means that it is interpreted as (a OP1 b) OP2 c , while right-associativity (right-to-left) means it is interpreted as a OP1 (b OP2 c) . Assignment operators are right-associative, so you can write:

with the expected result that a and b get the value 5. This is because the assignment operator returns the value that is assigned. First, b is set to 5. Then the a is also set to 5 — the return value of b = 5 , a.k.a. right operand of the assignment.

As another example, the unique exponentiation operator has right-associativity, whereas other arithmetic operators have left-associativity.

Operators are first grouped by precedence, and then, for adjacent operators that have the same precedence, by associativity. So, when mixing division and exponentiation, the exponentiation always comes before the division. For example, 2 ** 3 / 3 ** 2 results in 0.8888888888888888 because it is the same as (2 ** 3) / (3 ** 2) .

For prefix unary operators, suppose we have the following pattern:

where OP1 is a prefix unary operator and OP2 is a binary operator. If OP1 has higher precedence than OP2 , then it would be grouped as (OP1 a) OP2 b ; otherwise, it would be OP1 (a OP2 b) .

If the unary operator is on the second operand:

Then the binary operator OP2 must have lower precedence than the unary operator OP1 for it to be grouped as a OP2 (OP1 b) . For example, the following is invalid:

Because + has higher precedence than yield , this would become (a + yield) 1 — but because yield is a reserved word in generator functions, this would be a syntax error. Luckily, most unary operators have higher precedence than binary operators and do not suffer from this pitfall.

If we have two prefix unary operators:

Then the unary operator closer to the operand, OP2 , must have higher precedence than OP1 for it to be grouped as OP1 (OP2 a) . It's possible to get it the other way and end up with (OP1 OP2) a :

Because await has higher precedence than yield , this would become (await yield) 1 , which is awaiting an identifier called yield , and a syntax error. Similarly, if you have new !A; , because ! has lower precedence than new , this would become (new !) A , which is obviously invalid. (This code looks nonsensical to write anyway, since !A always produces a boolean, not a constructor function.)

For postfix unary operators (namely, ++ and -- ), the same rules apply. Luckily, both operators have higher precedence than any binary operator, so the grouping is always what you would expect. Moreover, because ++ evaluates to a value , not a reference , you can't chain multiple increments together either, as you may do in C.

Operator precedence will be handled recursively . For example, consider this expression:

First, we group operators with different precedence by decreasing levels of precedence.

  • The ** operator has the highest precedence, so it's grouped first.
  • Looking around the ** expression, it has * on the right and + on the left. * has higher precedence, so it's grouped first. * and / have the same precedence, so we group them together for now.
  • Looking around the * / / expression grouped in 2, because + has higher precedence than >> , the former is grouped.

Within the * / / group, because they are both left-associative, the left operand would be grouped.

Note that operator precedence and associativity only affect the order of evaluation of operators (the implicit grouping), but not the order of evaluation of operands . The operands are always evaluated from left-to-right. The higher-precedence expressions are always evaluated first, and their results are then composed according to the order of operator precedence.

If you are familiar with binary trees, think about it as a post-order traversal .

After all operators have been properly grouped, the binary operators would form a binary tree. Evaluation starts from the outermost group — which is the operator with the lowest precedence ( / in this case). The left operand of this operator is first evaluated, which may be composed of higher-precedence operators (such as a call expression echo("left", 4) ). After the left operand has been evaluated, the right operand is evaluated in the same fashion. Therefore, all leaf nodes — the echo() calls — would be visited left-to-right, regardless of the precedence of operators joining them.

Short-circuiting

In the previous section, we said "the higher-precedence expressions are always evaluated first" — this is generally true, but it has to be amended with the acknowledgement of short-circuiting , in which case an operand may not be evaluated at all.

Short-circuiting is jargon for conditional evaluation. For example, in the expression a && (b + c) , if a is falsy , then the sub-expression (b + c) will not even get evaluated, even if it is grouped and therefore has higher precedence than && . We could say that the logical AND operator ( && ) is "short-circuited". Along with logical AND, other short-circuited operators include logical OR ( || ), nullish coalescing ( ?? ), and optional chaining ( ?. ).

When evaluating a short-circuited operator, the left operand is always evaluated. The right operand will only be evaluated if the left operand cannot determine the result of the operation.

Note: The behavior of short-circuiting is baked in these operators. Other operators would always evaluate both operands, regardless if that's actually useful — for example, NaN * foo() will always call foo , even when the result would never be something other than NaN .

The previous model of a post-order traversal still stands. However, after the left subtree of a short-circuiting operator has been visited, the language will decide if the right operand needs to be evaluated. If not (for example, because the left operand of || is already truthy), the result is directly returned without visiting the right subtree.

Consider this case:

Only C() is evaluated, despite && having higher precedence. This does not mean that || has higher precedence in this case — it's exactly because (B() && A()) has higher precedence that causes it to be neglected as a whole. If it's re-arranged as:

Then the short-circuiting effect of && would only prevent C() from being evaluated, but because A() && C() as a whole is false , B() would still be evaluated.

However, note that short-circuiting does not change the final evaluation outcome. It only affects the evaluation of operands , not how operators are grouped — if evaluation of operands doesn't have side effects (for example, logging to the console, assigning to variables, throwing an error), short-circuiting would not be observable at all.

The assignment counterparts of these operators ( &&= , ||= , ??= ) are short-circuited as well. They are short-circuited in a way that the assignment does not happen at all.

The following table lists operators in order from highest precedence (18) to lowest precedence (1).

Several general notes about the table:

  • Not all syntax included here are "operators" in the strict sense. For example, spread ... and arrow => are typically not regarded as operators. However, we still included them to show how tightly they bind compared to other operators/expressions.
  • Some operators have certain operands that require expressions narrower than those produced by higher-precedence operators. For example, the right-hand side of member access . (precedence 17) must be an identifier instead of a grouped expression. The left-hand side of arrow => (precedence 2) must be an arguments list or a single identifier instead of some random expression.
  • Some operators have certain operands that accept expressions wider than those produced by higher-precedence operators. For example, the bracket-enclosed expression of bracket notation [ … ] (precedence 17) can be any expression, even comma (precedence 1) joined ones. These operators act as if that operand is "automatically grouped". In this case we will omit the associativity.
  • The operand can be any expression.
  • The "right-hand side" must be an identifier.
  • The "right-hand side" can be any expression.
  • The "right-hand side" is a comma-separated list of any expression with precedence > 1 (i.e. not comma expressions).
  • The operand must be a valid assignment target (identifier or property access). Its precedence means new Foo++ is (new Foo)++ (a syntax error) and not new (Foo++) (a TypeError: (Foo++) is not a constructor).
  • The operand must be a valid assignment target (identifier or property access).
  • The operand cannot be an identifier or a private property access.
  • The left-hand side cannot have precedence 14.
  • The operands cannot be a logical OR || or logical AND && operator without grouping.
  • The "left-hand side" must be a valid assignment target (identifier or property access).
  • The associativity means the two expressions after ? are implicitly grouped.
  • The "left-hand side" is a single identifier or a parenthesized parameter list.
  • Only valid inside object literals, array literals, or argument lists.

Python Tutorial

File handling, python modules, python numpy, python pandas, python matplotlib, python scipy, machine learning, python mysql, python mongodb, python reference, module reference, python how to, python examples, python assignment operators.

Assignment operators are used to assign values to variables:

Related Pages

Get Certified

COLOR PICKER

colorpicker

Contact Sales

If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail: [email protected]

Report Error

If you want to report an error, or if you want to make a suggestion, send us an e-mail: [email protected]

Top Tutorials

Top references, top examples, get certified.

Learn C++

21.12 — Overloading the assignment operator

The copy assignment operator (operator=) is used to copy values from one object to another already existing object .

Related content

As of C++11, C++ also supports “Move assignment”. We discuss move assignment in lesson 22.3 -- Move constructors and move assignment .

Copy assignment vs Copy constructor

The purpose of the copy constructor and the copy assignment operator are almost equivalent -- both copy one object to another. However, the copy constructor initializes new objects, whereas the assignment operator replaces the contents of existing objects.

The difference between the copy constructor and the copy assignment operator causes a lot of confusion for new programmers, but it’s really not all that difficult. Summarizing:

  • If a new object has to be created before the copying can occur, the copy constructor is used (note: this includes passing or returning objects by value).
  • If a new object does not have to be created before the copying can occur, the assignment operator is used.

Overloading the assignment operator

Overloading the copy assignment operator (operator=) is fairly straightforward, with one specific caveat that we’ll get to. The copy assignment operator must be overloaded as a member function.

This prints:

This should all be pretty straightforward by now. Our overloaded operator= returns *this, so that we can chain multiple assignments together:

Issues due to self-assignment

Here’s where things start to get a little more interesting. C++ allows self-assignment:

This will call f1.operator=(f1), and under the simplistic implementation above, all of the members will be assigned to themselves. In this particular example, the self-assignment causes each member to be assigned to itself, which has no overall impact, other than wasting time. In most cases, a self-assignment doesn’t need to do anything at all!

However, in cases where an assignment operator needs to dynamically assign memory, self-assignment can actually be dangerous:

First, run the program as it is. You’ll see that the program prints “Alex” as it should.

Now run the following program:

You’ll probably get garbage output. What happened?

Consider what happens in the overloaded operator= when the implicit object AND the passed in parameter (str) are both variable alex. In this case, m_data is the same as str.m_data. The first thing that happens is that the function checks to see if the implicit object already has a string. If so, it needs to delete it, so we don’t end up with a memory leak. In this case, m_data is allocated, so the function deletes m_data. But because str is the same as *this, the string that we wanted to copy has been deleted and m_data (and str.m_data) are dangling.

Later on, we allocate new memory to m_data (and str.m_data). So when we subsequently copy the data from str.m_data into m_data, we’re copying garbage, because str.m_data was never initialized.

Detecting and handling self-assignment

Fortunately, we can detect when self-assignment occurs. Here’s an updated implementation of our overloaded operator= for the MyString class:

By checking if the address of our implicit object is the same as the address of the object being passed in as a parameter, we can have our assignment operator just return immediately without doing any other work.

Because this is just a pointer comparison, it should be fast, and does not require operator== to be overloaded.

When not to handle self-assignment

Typically the self-assignment check is skipped for copy constructors. Because the object being copy constructed is newly created, the only case where the newly created object can be equal to the object being copied is when you try to initialize a newly defined object with itself:

In such cases, your compiler should warn you that c is an uninitialized variable.

Second, the self-assignment check may be omitted in classes that can naturally handle self-assignment. Consider this Fraction class assignment operator that has a self-assignment guard:

If the self-assignment guard did not exist, this function would still operate correctly during a self-assignment (because all of the operations done by the function can handle self-assignment properly).

Because self-assignment is a rare event, some prominent C++ gurus recommend omitting the self-assignment guard even in classes that would benefit from it. We do not recommend this, as we believe it’s a better practice to code defensively and then selectively optimize later.

The copy and swap idiom

A better way to handle self-assignment issues is via what’s called the copy and swap idiom. There’s a great writeup of how this idiom works on Stack Overflow .

The implicit copy assignment operator

Unlike other operators, the compiler will provide an implicit public copy assignment operator for your class if you do not provide a user-defined one. This assignment operator does memberwise assignment (which is essentially the same as the memberwise initialization that default copy constructors do).

Just like other constructors and operators, you can prevent assignments from being made by making your copy assignment operator private or using the delete keyword:

Note that if your class has const members, the compiler will instead define the implicit operator= as deleted. This is because const members can’t be assigned, so the compiler will assume your class should not be assignable.

If you want a class with const members to be assignable (for all members that aren’t const), you will need to explicitly overload operator= and manually assign each non-const member.

guest

operator-assignment

Require or disallow assignment operator shorthand where possible

Some problems reported by this rule are automatically fixable by the --fix command line option

JavaScript provides shorthand operators that combine variable assignment and some simple mathematical operations. For example, x = x + 4 can be shortened to x += 4 . The supported shorthand forms are as follows:

Rule Details

This rule requires or disallows assignment operator shorthand where possible.

The rule applies to the operators listed in the above table. It does not report the logical assignment operators &&= , ||= , and ??= because their short-circuiting behavior is different from the other assignment operators.

This rule has a single string option:

  • "always" (default) requires assignment operator shorthand where possible
  • "never" disallows assignment operator shorthand

Examples of incorrect code for this rule with the default "always" option:

Examples of correct code for this rule with the default "always" option:

Examples of incorrect code for this rule with the "never" option:

Examples of correct code for this rule with the "never" option:

When Not To Use It

Use of operator assignment shorthand is a stylistic choice. Leaving this rule turned off would allow developers to choose which style is more readable on a case-by-case basis.

This rule was introduced in ESLint v0.10.0.

  • Rule source
  • Tests source
  • Election 2024
  • Entertainment
  • Newsletters
  • Photography
  • Personal Finance
  • AP Investigations
  • AP Buyline Personal Finance
  • AP Buyline Shopping
  • Press Releases
  • Israel-Hamas War
  • Russia-Ukraine War
  • Global elections
  • Asia Pacific
  • Latin America
  • Middle East
  • Election Results
  • Delegate Tracker
  • AP & Elections
  • Auto Racing
  • 2024 Paris Olympic Games
  • Movie reviews
  • Book reviews
  • Personal finance
  • Financial Markets
  • Business Highlights
  • Financial wellness
  • Artificial Intelligence
  • Social Media

US energy panel approves rule to expand transmission of renewable power

FILE - Wind turbines work in Livermore, Calif., Aug. 10, 2022. Federal energy regulators on Monday, May 13, 2024, approved a long-awaited rule to expand the amount of renewable energy such as wind and solar power that is transmitted to the electric grid, a key part of President Joe Biden’s goal to decarbonize the economy by 2050. (AP Photo/Godofredo A. Vásquez, File)

FILE - Wind turbines work in Livermore, Calif., Aug. 10, 2022. Federal energy regulators on Monday, May 13, 2024, approved a long-awaited rule to expand the amount of renewable energy such as wind and solar power that is transmitted to the electric grid, a key part of President Joe Biden’s goal to decarbonize the economy by 2050. (AP Photo/Godofredo A. Vásquez, File)

The Federal Energy Regulatory Commission (FERC) is seen at right, Monday, May 13, 2024, in Washington. Federal energy regulators on Monday approved a long-awaited rule to expand the amount of renewable energy such as wind and solar power that is transmitted to the electric grid, a key part of President Joe Biden’s goal to decarbonize the economy by 2050. AP Photo/Jacquelyn Martin)

FILE - A solar farm sits Aug. 9, 2022, in Mona, Utah. Federal energy regulators on Monday, May 13, 2024, approved a long-awaited rule to expand the amount of renewable energy such as wind and solar power that is transmitted to the electric grid, a key part of President Joe Biden’s goal to decarbonize the economy by 2050. (AP Photo/Rick Bowmer, File)

FILE - Power utility lines are seen, Oct. 6, 2021, in Pownal, Maine. Federal energy regulators on Monday, May 13, 2024, approved a long-awaited rule to expand the amount of renewable energy such as wind and solar power that is transmitted to the electric grid, a key part of President Joe Biden’s goal to decarbonize the economy by 2050. (AP Photo/Robert F. Bukaty, File)

  • Copy Link copied

assignment operator rules

WASHINGTON (AP) — Federal energy regulators on Monday approved a long-awaited rule to make it easier to transmit renewable energy such as wind and solar power to the electric grid — a key part of President Joe Biden’s goal to eliminate carbon emissions economy-wide by 2050.

The rule, under development for two years, is aimed at boosting the nation’s aging power grid to meet surging demand fueled by huge data centers, electrification of vehicles and buildings, artificial intelligence and other uses.

The increased demand comes as coal-fired power plants continue to be retired amid competition from natural gas, and other energy sources face increasingly strict federal pollution rules, setting up what experts say could be a crisis for electric reliability.

The grid is also being tested by more frequent service disruptions during extreme weather events driven by climate change.

The Federal Energy Regulatory Commission approved the new rule, 2-1, with Chairman Willie Phillips and fellow Democratic commissioner Allison Clements voting in favor. Republican Mark Christie opposed the rule, dismissing it as a gift to solar and wind power operators.

FILE - The University of Maine's first prototype of an offshore wind turbine is seen in this Sept. 20, 2013 file photo, near Castine Maine. (AP Photo/Robert F. Bukaty, files)

The sprawling, 1,300-page rule, which addresses transmission planning and cost allocations, will enhance the country’s aging grid and ensure U.S. homes and businesses keep the lights on for decades to come, Phillips said.

“This rule cannot come fast enough,’' he said at a packed commission meeting at the agency’s Washington headquarters. “There is an urgent need to act to ensure the reliability and the affordability of our grid.’'

The U.S. power grid “is at a make-or-break moment’’ and is being tested every day, Phillips said, citing ”phenomenal load-growth from a domestic manufacturing boom, unprecedented construction of data centers fueling an AI revolution and ever-expanding electrification” of vehicles and buildings.

At the same time, aging infrastructure, shifting economics and a range of state and federal policies are leading traditional resources to retire, he said. “On top of all of this, extreme weather events have become the norm, and the electric grid is routinely being pushed to the brink.’'

At the same time, construction of high-voltage power lines declined to a record low in 2022, “and much of that construction was simply Band-Aid fixes, rather than building a visionary grid of the future,’' Phillips said.

Many power companies and Republican-led states don’t want to spend money on new transmission lines or upgrades for renewable energy, creating conflicts with Democratic states that have ambitious clean-energy goals.

Christie, the lone Republican on the three-member panel, said the rule “utterly fails to protect consumers″ and ensure reliable, low-priced power for American homes and businesses.

“Instead, this rule is a pretext to enact a sweeping policy agenda that Congress never passed,″ he said. The rule will likely result in “a massive transfer of wealth from consumers to for-profit special interests,″ primarily wind and solar operators, he said.

The rule is intended to streamline how power lines are sited and how costs are shared between states. It could accelerate construction of new transmission lines for wind, solar and other renewable power and add huge amounts of clean energy to the grid. Biden has set a goal of a carbon-free power sector by 2035, and net-zero carbon emissions economy-wide by 2050.

To meet those targets, the U.S. needs to more than double current regional transmission capacity and increase by five-fold the transmission lines between regions, according to an Energy Department study last year .

Under current rules, a large queue of utility-scale renewables cannot be connected to the grid because of a lack of available transmission capacity. The rule updates the agency’s planning process and seeks to determine how costs will be divided when transmission crosses state lines and goes through multiple operators of regional power grids.

White House climate adviser Ali Zaidi said the FERC rule adds momentum to what he called the ″historic progress″ led by Biden on clean energy. The new rule “will improve regional transmission planning, break down barriers to grid buildout and support the delivery of more affordable and reliable power,″ Zaidi said,

The new rule “is as common-sense as it is historic,’' Clements said, adding that it calls for more advanced planning and consideration of reliability and affordability of new power sources and fosters cooperation with states.

“Whether you’re planning a family vacation or the nation’s electricity system, planning early, taking a clear-eyed view of the options and making smart investment decisions will result in more affordable and reliable outcomes,’' she said.

Christie challenged the agency action.

Whether the policies promoted in the final rule “can be described as green, purple, red or blue is irrelevant,’' Christie said. “The point is that FERC as an independent agency has no business promoting the policies of any one party or presidential administration, especially when the effort to do so goes far beyond FERC’s legal authority.’'

Clements responded by calling the rule “straight down the middle’’ as a legal matter.

Democrats and clean-energy advocates hailed the new rule as a way to bring clean and cost-effective electricity onto the grid.

“Building more multi-state transmission lines unclogs the traffic jams on America’s electricity superhighways and unlocks our ability to keep up with our growing energy needs,’' said Heather O’Neill, president and CEO of Advanced Energy United, which represents renewable providers.

Senate Majority Leader Chuck Schumer, D-N.Y., said the rule will build on clean-energy incentives in the landmark climate law approved by Democrats in 2022.

The law, known as the Inflation Reduction Act, has been “a huge success,’' Schumer said Monday, “but much of that success would be lost without the ability to bring power from places that generate renewable energy to communities all across the country.’' FERC’s actions “will mean more low-cost, reliable clean energy for the places that need it most,’' he said.

MATTHEW DALY

  • Share full article

Advertisement

Supported by

New Rules to Overhaul Electric Grids Could Boost Wind and Solar Power

The Federal Energy Regulatory Commission approved the biggest changes in more than a decade to the way U.S. power lines are planned and funded.

Two workers in yellow safety vests and hard hats stand in the path of a high voltage power line.

By Brad Plumer

Reporting from Washington

Federal regulators on Monday approved sweeping changes to how America’s electric grids are planned and funded, in a move that supporters hope could spur thousands of miles of new high-voltage power lines and make it easier to add more wind and solar energy.

The new rule by the Federal Energy Regulatory Commission, which oversees interstate electricity transmission, is the most significant attempt in years to upgrade and expand the country’s creaking electricity network. Experts have warned that there aren’t nearly enough high-voltage power lines being built today, putting the country at greater risk of blackouts from extreme weather while making it harder to shift to renewable sources of energy and cope with rising electricity demand.

A big reason for the slow pace of grid expansion is that operators rarely plan for the long term, the commission said.

The nation’s three main electric grids are overseen by a patchwork of utilities and regional grid operators that mainly focus on ensuring the reliability of electricity to homes and businesses. When it comes to building new transmission lines, grid operators tend to be reactive, responding after a wind-farm developer asks to connect to the existing network or once a reliability problem is spotted.

The new federal rule , which was two years in the making, requires grid operators around the country to identify needs 20 years into the future, taking into account factors like changes in the energy mix, the growing number of states that require wind and solar power and the risks of extreme weather.

Grid planners would have to evaluate the benefits of new transmission lines, such as whether they would lower electricity costs or reduce the risk of blackouts, and develop methods for splitting the costs of those lines among customers and businesses.

“We must plan our nation’s grid for the long term,” said Willie Phillips, a Democrat who chairs the energy commission. “Our country’s aging grid is being tested in ways that we’ve never seen before. Without significant action now, we won’t be able to keep the lights on in the face of increasing demand, extreme weather, and new technologies.”

The commission approved the rule by a 2-1 vote, with the two Democratic commissioners in favor and the lone Republican, Mark Christie, opposed. Mr. Christie said the rule would allow states that want more renewable energy to unfairly pass on the costs of the necessary grid upgrades to their neighbors.

“This rule utterly fails to protect consumers,” said Mr. Christie. He said it “was intended to facilitate a massive transfer of wealth from consumers to for-profit, special interests, particularly wind and solar developers.”

It could take years for the rule to have an effect, and the commission could face legal challenges from states concerned about higher costs.

Nationwide, energy companies have proposed more than 11,000 wind, solar and battery projects, but many are in limbo because there’s not enough capacity on the grid to accommodate them. What’s more, individual developers are currently required to pay for grid upgrades to accommodate their projects in a process that is piecemeal and slow.

Some critics say that’s like asking a trucking company to pay for an additional lane on a highway that all motorists ultimately use. A better approach, they say, would be to plan ahead for broad upgrades with the costs shared by a wide set of energy providers and users.

But the question of who pays for those grid expansions has sparked furious debate.

Officials in states that are less enthusiastic about wind and solar power, like Kentucky or West Virginia, say they could be forced to foot the bill for new multibillion-dollar transmission lines meant to help states like New Jersey or Illinois fulfill their renewable energy ambitions.

To allay those concerns, the commission laid out guidelines around how to split the costs of new transmission projects. Before any lines are planned, utilities and grid operators are supposed to work with states on a formula for allocating costs to customers based on the potential benefits from the new lines.

There is some precedent for this. The grid that handles electricity in 15 Midwest states, known as MISO, recently approved $10.3 billion in new power lines, partly because many of its states have ambitious renewable energy goals that require more transmission. MISO estimated the lines would create up to $69 billion in total benefits , including lower fuel costs and fewer blackouts. The grid operator was then able to split the costs even among states that didn’t have renewable policies but would share in the rewards.

“It’s super hard, and not everyone got what they wanted, but we all agreed that we would sit in a room and figure this out,” said Carrie Zalewski, a former state regulator for Illinois who is now with the American Clean Power Association, a renewable energy trade group.

Mr. Christie said the final rule didn’t give states enough power to object to how the costs would be shared. But Allison Clements, the other Democrat on the commission, said that giving each state a veto was “a recipe for inaction.”

The rule would also require utilities and grid operators to consider new technologies that might cost more upfront but could make grids more efficient and deliver long-term benefits, such as advanced conductors that can carry twice as much current as traditional lines.

Environmental groups and renewable energy companies praised the new rules.

“This is a monumental day in the fight against climate change,” said Senator Chuck Schumer of New York, the Democratic majority leader, who had urged the commission to pass a forceful grid-planning rule.

Over the past year, Mr. Schumer and other Democrats have warned that efforts to fight climate change could fail if the nation’s grids aren’t overhauled. Power plants that burn coal and gas are a major source of the pollution that is dangerously heating the planet. While the 2022 Inflation Reduction Act poured hundreds of billions of dollars into cleaner alternatives like wind and solar power, one recent analysis found that half of the climate benefits of that law could be lost if the United States can’t build new transmission at a faster pace.

It remains to be seen how effective the new rule will be, since that will depend on how grid operators implement it. A 2011 attempt by the commission to encourage transmission planning largely faltered , in part because many utilities were opposed to new long-distance lines that might undercut their monopolies, said Ari Peskoe, director of the Electricity Law Initiative at Harvard Law School. Because of the decentralized nature of the nation’s grids, there is only so much that federal regulators can do to force operators to comply.

“I suspect this rule will be helpful in parts of the country where there’s already momentum for more transmission development” such as the Northeast, said Mr. Peskoe. “But in places where big utilities are resistant to more transmission, I don’t know if FERC can do that much.”

The new rule affects grid planning within 12 large regions around the country , but it wouldn’t require the planning of transmission to connect those different regions to each other, which some experts say is an even bigger need. The rule would also not affect the main grid in Texas, which is insulated from federal regulations because it doesn’t cross state lines.

The rule also doesn’t address the logistical and political challenges of constructing new long-distance power lines. It can take a decade or more for developers to locate a project through numerous jurisdictions, receive permits from a patchwork of different federal and state agencies and resolve lawsuits about spoiled views or damage to ecosystems.

The Biden administration recently finalized a program intended to cut the federal permitting time for certain large transmission lines in half. But speeding things up further might require action from Congress, where lawmakers have struggled to agree on new transmission policies.

In a separate rule on Monday, the federal energy commission did, however, outline certain situations in which it might override state objections to a small subset of new power lines.

At issue are a set of ten “national interest electric transmission corridors” that the Energy Department has tentatively identified across the country — places where new lines would be particularly beneficial. If state regulators either blocked or delayed a project in those corridors, the federal commission could step in to approve it.

But some experts question how often this would happen, since the commission has historically preferred to collaborate with states.

An earlier version of this article misspelled the given name of one of the commissioners. She is Allison Clements, not Alison.

How we handle corrections

Brad Plumer is a Times reporter who covers technology and policy efforts to address global warming. More about Brad Plumer

cppreference.com

Operator overloading.

Customizes the C++ operators for operands of user-defined types.

[ edit ] Syntax

Overloaded operators are functions with special function names:

[ edit ] Overloaded operators

When an operator appears in an expression , and at least one of its operands has a class type or an enumeration type , then overload resolution is used to determine the user-defined function to be called among all the functions whose signatures match the following:

Note: for overloading co_await , (since C++20) user-defined conversion functions , user-defined literals , allocation and deallocation see their respective articles.

Overloaded operators (but not the built-in operators) can be called using function notation:

[ edit ] Restrictions

  • The operators :: (scope resolution), . (member access), .* (member access through pointer to member), and ?: (ternary conditional) cannot be overloaded.
  • New operators such as ** , <> , or &| cannot be created.
  • It is not possible to change the precedence, grouping, or number of operands of operators.
  • The overload of operator -> must either return a raw pointer, or return an object (by reference or by value) for which operator -> is in turn overloaded.
  • The overloads of operators && and || lose short-circuit evaluation.

[ edit ] Canonical implementations

Besides the restrictions above, the language puts no other constraints on what the overloaded operators do, or on the return type (it does not participate in overload resolution), but in general, overloaded operators are expected to behave as similar as possible to the built-in operators: operator + is expected to add, rather than multiply its arguments, operator = is expected to assign, etc. The related operators are expected to behave similarly ( operator + and operator + = do the same addition-like operation). The return types are limited by the expressions in which the operator is expected to be used: for example, assignment operators return by reference to make it possible to write a = b = c = d , because the built-in operators allow that.

Commonly overloaded operators have the following typical, canonical forms: [1]

[ edit ] Assignment operator

The assignment operator ( operator = ) has special properties: see copy assignment and move assignment for details.

The canonical copy-assignment operator is expected to be safe on self-assignment , and to return the lhs by reference:

In those situations where copy assignment cannot benefit from resource reuse (it does not manage a heap-allocated array and does not have a (possibly transitive) member that does, such as a member std::vector or std::string ), there is a popular convenient shorthand: the copy-and-swap assignment operator, which takes its parameter by value (thus working as both copy- and move-assignment depending on the value category of the argument), swaps with the parameter, and lets the destructor clean it up.

This form automatically provides strong exception guarantee , but prohibits resource reuse.

[ edit ] Stream extraction and insertion

The overloads of operator>> and operator<< that take a std:: istream & or std:: ostream & as the left hand argument are known as insertion and extraction operators. Since they take the user-defined type as the right argument ( b in a @ b ), they must be implemented as non-members.

These operators are sometimes implemented as friend functions .

[ edit ] Function call operator

When a user-defined class overloads the function call operator, operator ( ) , it becomes a FunctionObject type.

An object of such a type can be used in a function call expression:

Many standard algorithms, from std:: sort to std:: accumulate accept FunctionObject s to customize behavior. There are no particularly notable canonical forms of operator ( ) , but to illustrate the usage:

[ edit ] Increment and decrement

When the postfix increment or decrement operator appears in an expression, the corresponding user-defined function ( operator ++ or operator -- ) is called with an integer argument 0 . Typically, it is implemented as T operator ++ ( int ) or T operator -- ( int ) , where the argument is ignored. The postfix increment and decrement operators are usually implemented in terms of the prefix versions:

Although the canonical implementations of the prefix increment and decrement operators return by reference, as with any operator overload, the return type is user-defined; for example the overloads of these operators for std::atomic return by value.

[ edit ] Binary arithmetic operators

Binary operators are typically implemented as non-members to maintain symmetry (for example, when adding a complex number and an integer, if operator+ is a member function of the complex type, then only complex + integer would compile, and not integer + complex ). Since for every binary arithmetic operator there exists a corresponding compound assignment operator, canonical forms of binary operators are implemented in terms of their compound assignments:

[ edit ] Comparison operators

Standard algorithms such as std:: sort and containers such as std:: set expect operator < to be defined, by default, for the user-provided types, and expect it to implement strict weak ordering (thus satisfying the Compare requirements). An idiomatic way to implement strict weak ordering for a structure is to use lexicographical comparison provided by std::tie :

Typically, once operator < is provided, the other relational operators are implemented in terms of operator < .

Likewise, the inequality operator is typically implemented in terms of operator == :

When three-way comparison (such as std::memcmp or std::string::compare ) is provided, all six two-way comparison operators may be expressed through that:

[ edit ] Array subscript operator

User-defined classes that provide array-like access that allows both reading and writing typically define two overloads for operator [ ] : const and non-const variants:

If the value type is known to be a scalar type, the const variant should return by value.

Where direct access to the elements of the container is not wanted or not possible or distinguishing between lvalue c [ i ] = v ; and rvalue v = c [ i ] ; usage, operator [ ] may return a proxy. See for example std::bitset::operator[] .

[ edit ] Bitwise arithmetic operators

User-defined classes and enumerations that implement the requirements of BitmaskType are required to overload the bitwise arithmetic operators operator & , operator | , operator ^ , operator~ , operator & = , operator | = , and operator ^ = , and may optionally overload the shift operators operator << operator >> , operator >>= , and operator <<= . The canonical implementations usually follow the pattern for binary arithmetic operators described above.

[ edit ] Boolean negation operator

[ edit ] rarely overloaded operators.

The following operators are rarely overloaded:

  • The address-of operator, operator & . If the unary & is applied to an lvalue of incomplete type and the complete type declares an overloaded operator & , it is unspecified whether the operator has the built-in meaning or the operator function is called. Because this operator may be overloaded, generic libraries use std::addressof to obtain addresses of objects of user-defined types. The best known example of a canonical overloaded operator& is the Microsoft class CComPtrBase . An example of this operator's use in EDSL can be found in boost.spirit .
  • The boolean logic operators, operator && and operator || . Unlike the built-in versions, the overloads cannot implement short-circuit evaluation. Also unlike the built-in versions, they do not sequence their left operand before the right one. (until C++17) In the standard library, these operators are only overloaded for std::valarray .
  • The comma operator, operator, . Unlike the built-in version, the overloads do not sequence their left operand before the right one. (until C++17) Because this operator may be overloaded, generic libraries use expressions such as a, void ( ) ,b instead of a,b to sequence execution of expressions of user-defined types. The boost library uses operator, in boost.assign , boost.spirit , and other libraries. The database access library SOCI also overloads operator, .
  • The member access through pointer to member operator - > * . There are no specific downsides to overloading this operator, but it is rarely used in practice. It was suggested that it could be part of a smart pointer interface , and in fact is used in that capacity by actors in boost.phoenix . It is more common in EDSLs such as cpp.react .

[ edit ] Notes

[ edit ] example, [ edit ] defect reports.

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

[ edit ] See also

  • Operator precedence
  • Alternative operator syntax
  • Argument-dependent lookup

[ edit ] External links

  • Recent changes
  • Offline version
  • What links here
  • Related changes
  • Upload file
  • Special pages
  • Printable version
  • Permanent link
  • Page information
  • In other languages
  • This page was last modified on 30 April 2024, at 17:49.
  • This page has been accessed 5,462,902 times.
  • Privacy policy
  • About cppreference.com
  • Disclaimers

Powered by MediaWiki

  • Java Arrays
  • Java Strings
  • Java Collection
  • Java 8 Tutorial
  • Java Multithreading
  • Java Exception Handling
  • Java Programs
  • Java Project
  • Java Collections Interview
  • Java Interview Questions
  • Spring Boot
  • Java Tutorial

Overview of Java

  • Introduction to Java
  • The Complete History of Java Programming Language
  • C++ vs Java vs Python
  • How to Download and Install Java for 64 bit machine?
  • Setting up the environment in Java
  • How to Download and Install Eclipse on Windows?
  • JDK in Java
  • How JVM Works - JVM Architecture?
  • Differences between JDK, JRE and JVM
  • Just In Time Compiler
  • Difference between JIT and JVM in Java
  • Difference between Byte Code and Machine Code
  • How is Java platform independent?

Basics of Java

  • Java Basic Syntax
  • Java Hello World Program
  • Java Data Types
  • Primitive data type vs. Object data type in Java with Examples
  • Java Identifiers

Operators in Java

  • Java Variables
  • Scope of Variables In Java

Wrapper Classes in Java

Input/output in java.

  • How to Take Input From User in Java?
  • Scanner Class in Java
  • Java.io.BufferedReader Class in Java
  • Difference Between Scanner and BufferedReader Class in Java
  • Ways to read input from console in Java
  • System.out.println in Java
  • Difference between print() and println() in Java
  • Formatted Output in Java using printf()
  • Fast I/O in Java in Competitive Programming

Flow Control in Java

  • Decision Making in Java (if, if-else, switch, break, continue, jump)
  • Java if statement with Examples
  • Java if-else
  • Java if-else-if ladder with Examples
  • Loops in Java
  • For Loop in Java
  • Java while loop with Examples
  • Java do-while loop with Examples
  • For-each loop in Java
  • Continue Statement in Java
  • Break statement in Java
  • Usage of Break keyword in Java
  • return keyword in Java
  • Java Arithmetic Operators with Examples
  • Java Unary Operator with Examples

Java Assignment Operators with Examples

  • Java Relational Operators with Examples
  • Java Logical Operators with Examples
  • Java Ternary Operator with Examples
  • Bitwise Operators in Java
  • Strings in Java
  • String class in Java
  • Java.lang.String class in Java | Set 2
  • Why Java Strings are Immutable?
  • StringBuffer class in Java
  • StringBuilder Class in Java with Examples
  • String vs StringBuilder vs StringBuffer in Java
  • StringTokenizer Class in Java
  • StringTokenizer Methods in Java with Examples | Set 2
  • StringJoiner Class in Java
  • Arrays in Java
  • Arrays class in Java
  • Multidimensional Arrays in Java
  • Different Ways To Declare And Initialize 2-D Array in Java
  • Jagged Array in Java
  • Final Arrays in Java
  • Reflection Array Class in Java
  • util.Arrays vs reflect.Array in Java with Examples

OOPS in Java

  • Object Oriented Programming (OOPs) Concept in Java
  • Why Java is not a purely Object-Oriented Language?
  • Classes and Objects in Java
  • Naming Conventions in Java
  • Java Methods

Access Modifiers in Java

  • Java Constructors
  • Four Main Object Oriented Programming Concepts of Java

Inheritance in Java

Abstraction in java, encapsulation in java, polymorphism in java, interfaces in java.

  • 'this' reference in Java
  • Inheritance and Constructors in Java
  • Java and Multiple Inheritance
  • Interfaces and Inheritance in Java
  • Association, Composition and Aggregation in Java
  • Comparison of Inheritance in C++ and Java
  • abstract keyword in java
  • Abstract Class in Java
  • Difference between Abstract Class and Interface in Java
  • Control Abstraction in Java with Examples
  • Difference Between Data Hiding and Abstraction in Java
  • Difference between Abstraction and Encapsulation in Java with Examples
  • Difference between Inheritance and Polymorphism
  • Dynamic Method Dispatch or Runtime Polymorphism in Java
  • Difference between Compile-time and Run-time Polymorphism in Java

Constructors in Java

  • Copy Constructor in Java
  • Constructor Overloading in Java
  • Constructor Chaining In Java with Examples
  • Private Constructors and Singleton Classes in Java

Methods in Java

  • Static methods vs Instance methods in Java
  • Abstract Method in Java with Examples
  • Overriding in Java
  • Method Overloading in Java
  • Difference Between Method Overloading and Method Overriding in Java
  • Differences between Interface and Class in Java
  • Functional Interfaces in Java
  • Nested Interface in Java
  • Marker interface in Java
  • Comparator Interface in Java with Examples
  • Need of Wrapper Classes in Java
  • Different Ways to Create the Instances of Wrapper Classes in Java
  • Character Class in Java
  • Java.Lang.Byte class in Java
  • Java.Lang.Short class in Java
  • Java.lang.Integer class in Java
  • Java.Lang.Long class in Java
  • Java.Lang.Float class in Java
  • Java.Lang.Double Class in Java
  • Java.lang.Boolean Class in Java
  • Autoboxing and Unboxing in Java
  • Type conversion in Java with Examples

Keywords in Java

  • Java Keywords
  • Important Keywords in Java
  • Super Keyword in Java
  • final Keyword in Java
  • static Keyword in Java
  • enum in Java
  • transient keyword in Java
  • volatile Keyword in Java
  • final, finally and finalize in Java
  • Public vs Protected vs Package vs Private Access Modifier in Java
  • Access and Non Access Modifiers in Java

Memory Allocation in Java

  • Java Memory Management
  • How are Java objects stored in memory?
  • Stack vs Heap Memory Allocation
  • How many types of memory areas are allocated by JVM?
  • Garbage Collection in Java
  • Types of JVM Garbage Collectors in Java with implementation details
  • Memory leaks in Java
  • Java Virtual Machine (JVM) Stack Area

Classes of Java

  • Understanding Classes and Objects in Java
  • Singleton Method Design Pattern in Java
  • Object Class in Java
  • Inner Class in Java
  • Throwable Class in Java with Examples

Packages in Java

  • Packages In Java
  • How to Create a Package in Java?
  • Java.util Package in Java
  • Java.lang package in Java
  • Java.io Package in Java
  • Java Collection Tutorial

Exception Handling in Java

  • Exceptions in Java
  • Types of Exception in Java with Examples
  • Checked vs Unchecked Exceptions in Java
  • Java Try Catch Block
  • Flow control in try catch finally in Java
  • throw and throws in Java
  • User-defined Custom Exception in Java
  • Chained Exceptions in Java
  • Null Pointer Exception In Java
  • Exception Handling with Method Overriding in Java
  • Multithreading in Java
  • Lifecycle and States of a Thread in Java
  • Java Thread Priority in Multithreading
  • Main thread in Java
  • Java.lang.Thread Class in Java
  • Runnable interface in Java
  • Naming a thread and fetching name of current thread in Java
  • What does start() function do in multithreading in Java?
  • Difference between Thread.start() and Thread.run() in Java
  • Thread.sleep() Method in Java With Examples
  • Synchronization in Java
  • Importance of Thread Synchronization in Java
  • Method and Block Synchronization in Java
  • Lock framework vs Thread synchronization in Java
  • Difference Between Atomic, Volatile and Synchronized in Java
  • Deadlock in Java Multithreading
  • Deadlock Prevention And Avoidance
  • Difference Between Lock and Monitor in Java Concurrency
  • Reentrant Lock in Java

File Handling in Java

  • Java.io.File Class in Java
  • Java Program to Create a New File
  • Different ways of Reading a text file in Java
  • Java Program to Write into a File
  • Delete a File Using Java
  • File Permissions in Java
  • FileWriter Class in Java
  • Java.io.FileDescriptor in Java
  • Java.io.RandomAccessFile Class Method | Set 1
  • Regular Expressions in Java
  • Regex Tutorial - How to write Regular Expressions?
  • Matcher pattern() method in Java with Examples
  • Pattern pattern() method in Java with Examples
  • Quantifiers in Java
  • java.lang.Character class methods | Set 1
  • Java IO : Input-output in Java with Examples
  • Java.io.Reader class in Java
  • Java.io.Writer Class in Java
  • Java.io.FileInputStream Class in Java
  • FileOutputStream in Java
  • Java.io.BufferedOutputStream class in Java
  • Java Networking
  • TCP/IP Model
  • User Datagram Protocol (UDP)
  • Differences between IPv4 and IPv6
  • Difference between Connection-oriented and Connection-less Services
  • Socket Programming in Java
  • java.net.ServerSocket Class in Java
  • URL Class in Java with Examples

JDBC - Java Database Connectivity

  • Introduction to JDBC (Java Database Connectivity)
  • JDBC Drivers
  • Establishing JDBC Connection in Java
  • Types of Statements in JDBC
  • JDBC Tutorial
  • Java 8 Features - Complete Tutorial

Operators constitute the basic building block of any programming language. Java too provides many types of operators which can be used according to the need to perform various calculations and functions, be it logical, arithmetic, relational, etc. They are classified based on the functionality they provide.

Types of Operators: 

  • Arithmetic Operators
  • Unary Operators
  • Assignment Operator
  • Relational Operators
  • Logical Operators
  • Ternary Operator
  • Bitwise Operators
  • Shift Operators

This article explains all that one needs to know regarding Assignment Operators. 

Assignment Operators

These operators are used to assign values to a variable. The left side operand of the assignment operator is a variable, and the right side operand of the assignment operator is a value. The value on the right side must be of the same data type of the operand on the left side. Otherwise, the compiler will raise an error. This means that the assignment operators have right to left associativity, i.e., the value given on the right-hand side of the operator is assigned to the variable on the left. Therefore, the right-hand side value must be declared before using it or should be a constant. The general format of the assignment operator is, 

Types of Assignment Operators in Java

The Assignment Operator is generally of two types. They are:

1. Simple Assignment Operator: The Simple Assignment Operator is used with the “=” sign where the left side consists of the operand and the right side consists of a value. The value of the right side must be of the same data type that has been defined on the left side.

2. Compound Assignment Operator: The Compound Operator is used where +,-,*, and / is used along with the = operator.

Let’s look at each of the assignment operators and how they operate: 

1. (=) operator: 

This is the most straightforward assignment operator, which is used to assign the value on the right to the variable on the left. This is the basic definition of an assignment operator and how it functions. 

Syntax:  

Example:  

2. (+=) operator: 

This operator is a compound of ‘+’ and ‘=’ operators. It operates by adding the current value of the variable on the left to the value on the right and then assigning the result to the operand on the left. 

Note: The compound assignment operator in Java performs implicit type casting. Let’s consider a scenario where x is an int variable with a value of 5. int x = 5; If you want to add the double value 4.5 to the integer variable x and print its value, there are two methods to achieve this: Method 1: x = x + 4.5 Method 2: x += 4.5 As per the previous example, you might think both of them are equal. But in reality, Method 1 will throw a runtime error stating the “i ncompatible types: possible lossy conversion from double to int “, Method 2 will run without any error and prints 9 as output.

Reason for the Above Calculation

Method 1 will result in a runtime error stating “incompatible types: possible lossy conversion from double to int.” The reason is that the addition of an int and a double results in a double value. Assigning this double value back to the int variable x requires an explicit type casting because it may result in a loss of precision. Without the explicit cast, the compiler throws an error. Method 2 will run without any error and print the value 9 as output. The compound assignment operator += performs an implicit type conversion, also known as an automatic narrowing primitive conversion from double to int . It is equivalent to x = (int) (x + 4.5) , where the result of the addition is explicitly cast to an int . The fractional part of the double value is truncated, and the resulting int value is assigned back to x . It is advisable to use Method 2 ( x += 4.5 ) to avoid runtime errors and to obtain the desired output.

Same automatic narrowing primitive conversion is applicable for other compound assignment operators as well, including -= , *= , /= , and %= .

3. (-=) operator: 

This operator is a compound of ‘-‘ and ‘=’ operators. It operates by subtracting the variable’s value on the right from the current value of the variable on the left and then assigning the result to the operand on the left. 

4. (*=) operator:

 This operator is a compound of ‘*’ and ‘=’ operators. It operates by multiplying the current value of the variable on the left to the value on the right and then assigning the result to the operand on the left. 

5. (/=) operator: 

This operator is a compound of ‘/’ and ‘=’ operators. It operates by dividing the current value of the variable on the left by the value on the right and then assigning the quotient to the operand on the left. 

6. (%=) operator: 

This operator is a compound of ‘%’ and ‘=’ operators. It operates by dividing the current value of the variable on the left by the value on the right and then assigning the remainder to the operand on the left. 

Please Login to comment...

Similar reads.

  • Java-Operators

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

India's Bharti Airtel posts Q4 revenue miss on currency devaluation in Africa

  • Medium Text

A man leaves a Bharti Airtel store in New Delhi

Sign up here.

Reporting by Kashish Tandon in Bengaluru; Editing by Sohini Goswami

Our Standards: The Thomson Reuters Trust Principles. New Tab , opens new tab

GSMA's 2023 Mobile World Congress (MWC) in Barcelona

Business Chevron

International Monetary Fund spokesperson Julie Kozack speaks to reporters at the IMF's headquarters, in Washington

IMF: U.S. should keep open trade, work with China to resolve disputes

The U.S. would be better served by maintaining its open trade system rather than imposing new punitive duties on Chinese goods, the International Monetary Fund said on Thursday, adding that Washington and Beijing should work together to resolve their trade tensions.

The sign on a Taco Bell restaurant advertises

IMAGES

  1. Assignment Operators in Java with Examples

    assignment operator rules

  2. Assignment Operators in C

    assignment operator rules

  3. PPT

    assignment operator rules

  4. PPT

    assignment operator rules

  5. How Matlab Assignment Operator Works (Example)

    assignment operator rules

  6. PPT

    assignment operator rules

VIDEO

  1. ASSIGNMENT ON BREAKING THE RULES

  2. Synchronous Seq circuits state assignment rules

  3. ASSIGNMENT WORK RULES

  4. Operator Overloading Part 2

  5. Assignment Operator & Comparison Operator in Javascript

  6. Core

COMMENTS

  1. Assignment Operators in Programming

    Assignment operators are used in programming to assign values to variables. We use an assignment operator to store and update data within a program. They enable programmers to store data in variables and manipulate that data. The most common assignment operator is the equals sign (=), which assigns the value on the right side of the operator to ...

  2. Assignment (=)

    The assignment operator is completely different from the equals (=) sign used as syntactic separators in other locations, which include:Initializers of var, let, and const declarations; Default values of destructuring; Default parameters; Initializers of class fields; All these places accept an assignment expression on the right-hand side of the =, so if you have multiple equals signs chained ...

  3. Assignment operators

    for assignments to class type objects, the right operand could be an initializer list only when the assignment is defined by a user-defined assignment operator. removed user-defined assignment constraint. CWG 1538. C++11. E1 ={E2} was equivalent to E1 = T(E2) ( T is the type of E1 ), this introduced a C-style cast. it is equivalent to E1 = T{E2}

  4. Python's Assignment Operator: Write Robust Assignments

    To create a new variable or to update the value of an existing one in Python, you'll use an assignment statement. This statement has the following three components: A left operand, which must be a variable. The assignment operator ( =) A right operand, which can be a concrete value, an object, or an expression.

  5. Assignment Operators in C

    Different types of assignment operators are shown below: 1. "=": This is the simplest assignment operator. This operator is used to assign the value on the right to the variable on the left. Example: a = 10; b = 20; ch = 'y'; 2. "+=": This operator is combination of '+' and '=' operators. This operator first adds the current ...

  6. Assignment Operators in Python

    The Walrus Operator in Python is a new assignment operator which is introduced in Python version 3.8 and higher. This operator is used to assign a value to a variable within an expression. Syntax: a := expression. Example: In this code, we have a Python list of integers. We have used Python Walrus assignment operator within the Python while loop.

  7. 4.6: Assignment Operator

    This operator first subtracts the current value of the variable on left from the value on the right and then assigns the result to the variable on the left. Example: (a -= b) can be written as (a = a - b) If initially value 8 is stored in the variable a, then (a -= 6) is equal to 2. (the same as a = a - 6)

  8. Expressions and operators

    An assignment operator assigns a value to its left operand based on the value of its right operand. The simple assignment operator is equal (=), which assigns the value of its right operand to its left operand.That is, x = f() is an assignment expression that assigns the value of f() to x. There are also compound assignment operators that are shorthand for the operations listed in the ...

  9. Assignment Operators in C

    Simple assignment operator. Assigns values from right side operands to left side operand. C = A + B will assign the value of A + B to C. +=. Add AND assignment operator. It adds the right operand to the left operand and assign the result to the left operand. C += A is equivalent to C = C + A. -=.

  10. Assignment operator (C++)

    In the C++ programming language, the assignment operator, =, is the operator used for assignment. Like most other operators in C++, it can be overloaded . The copy assignment operator, often just called the "assignment operator", is a special case of assignment operator where the source (right-hand side) and destination (left-hand side) are of ...

  11. PEP 572

    Unparenthesized assignment expressions are prohibited for the value of a keyword argument in a call. Example: foo(x = y := f(x)) # INVALID foo(x=(y := f(x))) # Valid, though probably confusing. This rule is included to disallow excessively confusing code, and because parsing keyword arguments is complex enough already.

  12. Assignment, Arithmetic, and Unary Operators

    This operator can also be used on objects to assign object references, as discussed in Creating Objects. The Arithmetic Operators. The Java programming language provides operators that perform addition, subtraction, multiplication, and division. There's a good chance you'll recognize them by their counterparts in basic mathematics.

  13. Assignment operators

    Assignment operators. Assignment operators modify the value of the object. 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 ...

  14. Operator precedence

    This is because the assignment operator returns the value that is assigned. First, b is set to 5. Then the a is also set to 5 — the return value of b = 5, a.k.a. right operand of the assignment. As another example, the unique exponentiation operator has right-associativity, whereas other arithmetic operators have left-associativity.

  15. Python Assignment Operators

    Python Assignment Operators. Assignment operators are used to assign values to variables: Operator. Example. Same As. Try it. =. x = 5. x = 5.

  16. C Operator Precedence

    This rule grammatically forbids some expressions that would be semantically invalid anyway. Some compilers ignore this rule and detect the invalidity semantically. ... In C++, the conditional operator has the same precedence as assignment operators, and prefix ++ and --and assignment operators don't have the restrictions about their operands.

  17. 21.12

    21.12 — Overloading the assignment operator. Alex November 27, 2023. The copy assignment operator (operator=) is used to copy values from one object to another already existing object. As of C++11, C++ also supports "Move assignment". We discuss move assignment in lesson 22.3 -- Move constructors and move assignment .

  18. The rule of three/five/zero

    Rule of three. If a class requires a user-defined destructor, a user-defined copy constructor, or a user-defined copy assignment operator, it almost certainly requires all three. Because C++ copies and copy-assigns objects of user-defined types in various situations (passing/returning by value, manipulating a container, etc), these special ...

  19. Assignment Operators In C++

    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. Syntax. variable += value; This above expression is equivalent to the expression: variable = variable + value; Example.

  20. Copy assignment operator

    Triviality of eligible copy assignment operators determines whether the class is a trivially copyable type. [] NoteIf both copy and move assignment operators are provided, overload resolution selects the move assignment if the argument is an rvalue (either a prvalue such as a nameless temporary or an xvalue such as the result of std::move), and selects the copy assignment if the argument is an ...

  21. c++

    ClassName = Other.ClassName; return *this; } This is the general convention used when overloading operator=. The return statement allows chaining of assignments (like a = b = c) and passing the parameter by const reference avoids copying Other on its way into the function call. edited Dec 22, 2010 at 13:54.

  22. operator-assignment

    Use of operator assignment shorthand is a stylistic choice. Leaving this rule turned off would allow developers to choose which style is more readable on a case-by-case basis. Version

  23. US energy panel approves rule to expand transmission of renewable power

    The rule updates the agency's planning process and seeks to determine how costs will be divided when transmission crosses state lines and goes through multiple operators of regional power grids. White House climate adviser Ali Zaidi said the FERC rule adds momentum to what he called the ″historic progress″ led by Biden on clean energy.

  24. Ukraine emergency power cuts cancelled, grid operator says

    May 14, 202411:35 PM PDTUpdated 3 min ago. May 15 (Reuters) - Ukrainian grid operator Ukrenergo has cancelled previously imposed emergency country-wide power cuts, private energy firm DTEK said on ...

  25. Futures exchange operator CME Group plans to launch bitcoin trading, FT

    May 16 (Reuters) - CME Group (CME.O), the world's largest futures exchange operator, plans to launch bitcoin trading to expand its portfolio, the Financial Times reported on Thursday. The Chicago ...

  26. New Rules to Overhaul Electric Grids Could Boost Wind and Solar Power

    The rule would also require utilities and grid operators to consider new technologies that might cost more upfront but could make grids more efficient and deliver long-term benefits, such as ...

  27. Grid operator TenneT could sell or list German assets

    Dutch electricity grid operator TenneT will consider selling or listing its German operations, it said on Thursday, with the Netherlands and Germany having failed to agree a sale to the German state.

  28. operator overloading

    In those situations where copy assignment cannot benefit from resource reuse (it does not manage a heap-allocated array and does not have a (possibly transitive) member that does, such as a member std::vector or std::string), there is a popular convenient shorthand: the copy-and-swap assignment operator, which takes its parameter by value (thus working as both copy- and move-assignment ...

  29. Java Assignment Operators with Examples

    variable operator value; Types of Assignment Operators in Java. The Assignment Operator is generally of two types. They are: 1. Simple Assignment Operator: The Simple Assignment Operator is used with the "=" sign where the left side consists of the operand and the right side consists of a value. The value of the right side must be of the same data type that has been defined on the left side.

  30. India's Bharti Airtel posts Q4 revenue miss on currency devaluation in

    Earlier in the day, Airtel's unit Bharti Hexacom (BHAX.NS) posted a 10.4% year-on-year climb in fourth-quarter profit, led by a climb in its average revenue per user. Airtel's shares settled 0.1% ...