Open In App

Order of Evaluation in C++17

Last Updated : 06 Sep, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

In C++ programming, the order of evaluation of expressions can have a significant impact on the behavior and correctness of the code. C++17 introduced changes to the order of evaluation rules, providing clearer guidelines and improving consistency across different compilers. In this article, we will explore the order of evaluation in C++17 and understand its implications.

Need of Order of Evaluation Rules in C++17

  1. In a program, when the same memory location has to be modified by multiple operations within the program and the operations are unsequenced, this can lead to undefined behavior.
  2. In a program, if one operation modifies a memory location and the same memory location is used in an evaluation, but these actions are unsequenced, this can also lead to undefined behavior.

Due to these possible undefined behaviors, C++ 17 defined rules for Order of Evaluation.

Order of Evaluation Rules in C++17

C++17 introduced the following rules for the order of evaluation:

  1. Left-to-right Evaluation: C++17 guarantees that subexpressions within an expression are evaluated from left to right. This means that the leftmost subexpression is evaluated first, followed by the next subexpression on the right, and so on.
  2. Sequenced Before Relationship: If two subexpressions within an expression are not directly related by a common sequence point, C++17 guarantees that they will be evaluated in an order that is either left-to-right or according to the dependencies imposed by the expressions themselves.
  3. Function Call Sequencing: When you call a function, evaluations related to the arguments of the called function are evaluated before the evaluation of called function.
  4. Indeterminately Sequenced Expressions: C++17 allows for expressions that are indeterminately sequenced. This means that the order of evaluation between these expressions is unspecified, and the compiler has the freedom to choose the order.
  5. Post-Increment/Decrement Sequencing: When using x++ or x--, the value is first used, then increased/decreased.
  6. Pre-Increment/Decrement Sequencing: For ++x or --x, the value is increased/decreased before being used.
  7. Logical AND/OR Sequencing: In && and ||, the left part is evaluated before the right.
  8. Conditional Operator Sequencing: In the ? : operator, the left part is evaluated before the right parts.
  9. Assignment Operator Sequencing: For = and +=, the right value is evaluated first, then the left value is updated.
  10. Comma Operator Sequencing: In the , operator, the left part is evaluated before the right part.
  11. List-Initialization Sequencing: When initializing multiple values, calculations and side effect for each value is done before moving to the next value.
  12. Indeterminate Function Call Sequencing: Usually, function calls are done in a specific order, but if they are indeterminately sequenced, the compiler can decide the sequence of evaluation.
  13. Allocation and Constructor Sequencing: When we create objects using new keyword, the evaluation of constructor arguments is done before the memory is allocated to the object.
  14. Return and Destructor Sequencing: When a function returns, operations on the temporary data is sequenced before, then the local variables are destroyed.
  15. When calling a function, the name of the function specifying the function call is evaluated before the arguments passed in the function.
  16. When we overloads an operator and use it in a program, if follows the same order of evaluation as the built in operator that is overloaded.
  17. When we access an array element using square brackets like arr[I], the evaluation and side effects related to the expression arr are sequenced before the evaluation of expression inside the square brackets.
  18. When we use shift operators in a program like num << shift_value, the evaluations and side effects related to expression num is sequenced before evaluation of expression shift_value.
  19. In simple assignment variable = value and compound assignments like variable @= value, the evaluation and side effect related to expression value is sequenced before the evaluation and side effect related to variable.
  20. The evaluation of comma separated expressions within a parenthesis are evaluated indeterminately.

Example: C++ Program to Illustrate the Order of Evaluation

C++




#include <iostream>
using namespace std;
  
int getValue() {
  return 42; 
}
  
int main()
{
    int a = 0;
    int b = a++ + getValue();
  
    cout << "a: " << a << endl;
    cout << "b: " << b << endl;
  
    return 0;
}


Output

a: 1
b: 42



Explanation

In the above example, we have an expression a++ + getValue(), first the value of a is used in the operation then the value of a is incremented and getValue() returns a value. The order of evaluation determines whether a++ or getValue() is evaluated first. In C++17, the order of evaluation is left-to-right, so a++ is evaluated before getValue().

Conclusion

The order of evaluation in C++17 is crucial for writing correct and predictable code. With the introduced rules of left-to-right evaluation, sequenced before relationship, and indeterminately sequenced expressions, C++17 provides clearer guidelines for the order of evaluation. By understanding and applying the rules of order of evaluation in C++17, we can write robust and reliable code that works consistently across different compilers and platforms. Take advantage of the improved guidelines provided by C++17.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads