Evaluation of expressions in C + + languages

Source: Internet
Author: User

Reprint Address: http://www.cnblogs.com/heyonggang/p/3340301.html

Here, first Salute to miss Jo!

Qiu Zongyan: Evaluation of expressions in C + + languages

You can often see the following question in some of the discussion groups: "Who knows what value is assigned to n in the C statement below?" ”
m = 1; n = m+++m++;
Recently an unknown friend sent me an email asking why in a C + + system, the following expression prints two 4 instead of 4 and 5:
A = 4; cout << a++ << A;
is C + + not a rule << operation left combination? is the C + + book wrong, or is there a problem with the implementation of this system?

Note: Run a = 4; cout << a++ << A; in Visual C + + 6.0, you get 4 and 4; In Visual Studio, you get 4 and 5. Which one is right? Please look at the following analysis!

One question to understand is: If a variable is modified somewhere in the program (by assignment, increment/decrement, etc.), when will the new value be taken from the variable? Some might say, "What a problem!" I modified the variable, and then the value from this variable, take the value of course is modified! "It's not that simple, actually.
The C + + language is "expression-based language, all calculations, including assignments, are done in an expression. "x = 1;" is the expression "x = 1" followed by a semicolon that represents the end of the statement. To understand the meaning of the program, first of all, the meaning of the expression is understood, that is: 1) The calculation process determined by the expression; 2) it has an impact on the environment, which can regard the environment as all the variables available at that time. If an expression (or subexpression) evaluates only the value without altering the environment, we say that it is a reference transparent, and that the early calculation of this expression has no effect on other calculations (the environment does not change the calculation.) Of course, its value may be affected by other calculations). If an expression not only calculates a value, but also modifies the environment, it is said that the expression hasSide Effects(because it does extra work). a++ are expressions that have side effects. These statements also apply to similar problems in other languages.
Now the question becomes: if there is a side effect of an expression (part) in a C + + program, when will this side effect actually manifest in use? To make the problem clearer, we assume that there is a code snippet in the program "... a[i]++ ... a[j ...", assuming that the values of I and J are exactly equal (A[i] and A[j] exactly refer to the same array element); Assuming a[i]++ is true before a[j], assuming no other modifications in the meantime a[ I] 's action. Under these assumptions, can the modifications of a[i]++ to A[i] be reflected in the evaluation of A[J]? Note: Since I and J are not statically determined, in the target code, access to the two array elements (access to memory) must be done through two separate pieces of code. The computation of modern computers is done in registers, and the question now becomes: is the value of A[i] Updated (from the register) to memory before the code that takes the A[j] value is executed? The answer to this question is clear if you understand the language's provisions in this regard.
programming languages usually specify the latest implementation time (called Sequential point, order point, or execution point) for variable modification in execution。 There is a sequence of sequential points (moments) in the execution of the program, and the language guarantees that once the execution arrives at a sequential point, all modifications (side effects) that occurred prior to this must be implemented (must be reflected in subsequent accesses to the same storage location), and all modifications thereafter have not occurred. There is no guarantee between the order points. The concept of sequential points is particularly important for languages that allow expressions with the C + + language to have side effects.
Now the answer to the above question is clear: if there is a sequential point between a[i]++ and A[j], then it is guaranteed that a[j] will get the modified value, otherwise there is no guarantee.
The concept of sequential points is clearly defined in the C + + language definition (Language reference manual).The order point is located
1. At the end of each complete expression. The complete expression includes a variable initialization expression, an expression statement, an expression for the return statement, and a control expression for the condition, loop, and switch statement (for header with three control expressions);
2. Operator &&, | |,?: and the first operand of the comma operator after the calculation;
3. After the evaluation of all actual and function name expressions in the function call (the function that needs to be called may also be described by an expression), after the completion (before entering the function body).
Assuming Ti and ti+1 are the two sequential points successively, to the ti+1, any C + + system (VC, BC, etc.) must implement all the side effects of TI. Of course they can also not wait until the moment ti+1, can choose at any time between the time period [T, Ti+1] to achieve the side effects during this period, because the C + + language allows these choices.
The previous discussion assumes that a[i]++ was done before A[i]. Whether or not the a[i]++ is done first in a program fragment is also related to the calculation process determined by the expression in which it is located. We are familiar with the rules of the C + + language regarding precedence, binding, and parentheses, and the order of computation when multiple operands are present is often overlooked. Look at the following example:
(A + B) * (C + D) Fun (a++, B, a+5)
Which of the two operands in this "*" is counted first? What is the order of fun and its three parameters? It doesn't matter if the first expression is in any order of calculation, because the sub-expressions areReference TransparentOf In the second example, the argument expression has side effects, and the order of calculation is very important. A few languages explicitly specify the order in which operands are computed (Java rules from left to right), C + + is intentionally not specified, and there is no calculation order for two objects for most two-dollar operations (except for the &&, | | | And, nor does it specify the order in which the function parameters and the function are evaluated. When the second expression is computed, the fun, a++, B, and a+5 are counted first in some order, followed by sequential points, and then into function execution.
Many books are wrong on these issues (including some very popular books). For example, C + + is counted to the left (or to the right), or to a C + + system that calculates one side first. These statements are all wrong! A C + + system can always count to the left or always to the right, or sometimes to the left, sometimes to the right, or in the same expression, sometimes to the left, sometimes to the right. Different systems may be in different order (because they all conform to the language standard), different versions of the same system can be used in different ways, and the same version may be in different order in different locations under different optimization methods. Because these practices are in line with the language specification. It is also important to note the problem of order points here: even if one side of the expression first forget, its side effects may not be reflected in memory, so on the other side of the calculation has no effect.
Back to the previous example: "Who knows what value is assigned to n in the C statement below?" ”
m = 1; n = m++ +m++;
The correct answer is:I don't know! The language does not stipulate what it should work out, and the result depends entirely on the specific processing of the specific system in the specific context. It involves the evaluation order of operands and the realization of variable modification. For:
cout << a++ << A;
We know it's
(Cout.operator << (a++)). Operator << (a);
The shorthand. Look at the outer function call first, you need to figure out the function used, and you need to calculate the value of a. The language does not specify which to count first. If the function is really first calculated, there is another function call in this calculation, and there is a sequential point before the body of the tuned function is executed, and then the side effects of a++ are realized. If the parameter is calculated first, the value of a is 4, and then the side effect of the function is not changed (in this case output two 4). Of course, these are just assumptions, actually should say: this kind of thing should not write, discuss its effect is meaningless.
It may be said that why do people design C + + without the order of clarity, to avoid the trouble? The C + + language approach is purely intentional,The purpose of this is to allow the compiler to take any order of evaluation, so that the compiler can adjust the sequence of instructions that implement the expression evaluation as needed in the optimization to get more efficient code. The order and effect of expression evaluation, like Java, not only limits the way languages are implemented, but also requires more frequent memory accesses (to achieve side effects), which can result in considerable loss of efficiency. It should be said that, in this issue, C + + and Java have been chosen to implement their respective design principles, each has been (C + + potential efficiency, Java clearer program behavior), of course, also lost. It should also be noted that the majority of programming languages actually use a similar rule that is analogous to C + +.
Having discussed so much, what conclusions should be drawn? The C + + language rules tell us thatany expression that relies on a particular calculation order and relies on a modification effect between sequential points is not guaranteed. The rules that should be implemented in the program design are:If there are multiple references to the same "variable" in any "full expression" (a calculation that ends in a sequence of points), then there should be no side effects on the "variable" in the expression. Otherwise, the expected results cannot be guaranteed. Note: The problem here is not a try on a system, because it is not possible to experiment with all possible combinations of expressions and all possible contexts. The discussion here is about language, not an implementation. In a word, never write this expression, or we'll have trouble in some kind of environment sooner or earlier.
PostScript: Last year to attend an academic conference, saw peers write articles to discuss a C system in what order the expression is evaluated, and summed up some "laws." Learn from the discussion of a "programmer level test" out of this type of topic. It makes me feel very uneasy. This year to a teacher class lectures, found that many professional teachers are also not very clear about this basic problem, but also feel that the problem is really serious. Therefore, we will arrange this short article for your reference.
Post-PostScript: More than 4 years later, many new and old textbooks are still taking pains to discuss the original meaningless questions in C (as noted in this article). People who want to learn and use C don't get caught up in it.


Reference: http://bbs.csdn.net/topics/370153775


This article is from the "whatever957" blog, make sure to keep this source http://whatever957.blog.51cto.com/6835003/1659413

Evaluation of expressions in C + + languages

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.