thing is that in some complex calculations as b=a++*c you do not know what will happen.
everything C + + is a promise that after this line is about to be increased by one, but does not say if it will be before or after multiplication. means that you have a great mistake in the future work, if you were 5 and c i 7 respectively, then get your očekicani result was B = 42 and you can get that b = 42, but you have no guarantee for it, just so you could get b = 35th
or if you need to do print court <<"b =" <<a + +, C + + again, guaranteeing that after you Mukah lines are for, but does not guarantee that it will print the new value.
it all depends on the compiler to compiler. even every compiler will not always do the same order, but going the way it is "easier." I hope you know this was helpful
(These examples are relatively simple calculations, and give relatively large errors, imagine what happens when you have a longer calculations)
However, justAbeginner, ANSI C++ is an international standard. If such a simple thing as order of operations varies from compiler to compiler, then the writers of the compiler are doing something wrong, and the writers of the most-used compilers in the world are part of the GNU project and Microsoft... *omitted, as the translator that translates my thoughts to English or vice versa had long since shut down*
1
Supplement Lecture: Myths of expressions with side effects
One of the features of C and C + +, which are quite different from conventional programming effects of the
existence of so-called. expressions with side effects (English side effects). These are expressions that, in addition to products
some value, causing some accompanying effects, usually change the value of some of the variables.
The simplest examples of expressions with side effects such expressions like "a = 5", "a + = 2" or "a +" whose
the Administration side effect - it changes the value of variable "a", although all these terms have their
result, which is important if they use this podizrazi in a more complex expression. For instance, in
All three of these examples, the value of these expressions is precisely the new value of variable "a" after
changes. According to this expression like "a +" differs from expressions like "a + +", which also increases the value
variable "a", but at the same value of the old value of the variable expression "a", ie the value
this variable before the change. This difference is reflected in more complex expressions like "3 + 2 * (+ + a)"
or "3 + 2 * (a ++)". In both of these expressions, as we have a side effect of increasing the value
variable "a" for 1, but in the first case to calculate the whole expression to be used a new
value of variable "a", while in the second case to be used the old value of variable
"A". However, as we shall soon see, in any event not to be understood that the value
variable "a" need to be increased only after the computation of the whole phrase, as many beginners think.
It should be noted that all the expressions that perform any action that is not a mere calculation
value of the expression should be seen as expressions with side effects. Such are, for example, expressions that perform some
printing on an output device, such as "court <<12 + 15" or "printf ("% d ", 12 + 15). Both expressions produce
the same side effect - printing characters "27" (the result of calculating the 12 +15) on the output device. However, the result
these expressions is 27th Actually, the result of the first term is the very structure "court" (which we talked about when we
talked about the concatenation operator "<<"), while the result of the second term the number of written characters, and 2
in this example. This characteristic function "printf" start-ups are usually not known. Thus, although
the result of "printf" function is usually ignored and used only its side effects (printing), an expression like
"A = printf ("% d ", 12 + 15)" it is entirely legal and locates the value 2 in the variable "a" (in addition to
the fact that, of course, printed characters "27" on the output device).
This would all stories on expressions with side effects was over, that there is an unfortunate fact
for which expressions with side effects should be used extremely carefully. Specifically, the specification language C
C + + says that if in some expression of a variable applies side effect (ie, if the expression
changing its value), this variable within this expression may only appear in one place. In
Otherwise, the result of making such an expression is unpredictable (more precisely, its result depends on the
specific performance compiler) regardless of what is syntactically correct (ie, the compiler will not be in such a
term report any error)! This is especially important to point out, considering that this fact
rarely indicated in the available literature, a beginner (especially a bit braver) often have a tendency that
The reason for this is not exactly a happy feature of C and C + +
The presentations will explain below.
In the first place, it should be noted that C + + language does not stipulate that the order will be calculated
some parts of the expressions that constitute a complex expression. For example, the expression of the form "x + y" where "x" and
"Y" is also expressed, "x" and "y" will certainly be finalized before you start adding up, but there is no
no rule that you will first be calculated podizraz "x" or podizraz "y". This ambiguity allows
compiler that I choose the order of computation, which in this case more appropriate, given that
sometimes better to first calculate the "x" and then "y", and sometimes vice versa. For example, the expression "a * b * c + a * b"
it is better to first calculate the second addend, since its value can be used to compute the first
sabirka. Of course, if the expression contains no side effects, the end result can not depend on the order of
which are calculated its individual parts. However, if the expression has side effects, it is no longer
cases, the end result can certainly depend on the order of calculation. Let's look at an example
the expression "a * a + +". It is known that the value of the right operand for multiplication value
variable "a" before the increase, and that the variable "a" to be increased by 1, but it is not known whether such
Left side will be used for multiplication value of variable "a" before and after
2
zoom (it depends on whether it is the first consideration in left or right operand for multiplication). As
Consequently, the value of this expression is unpredictable and depends on the actual performance
compiler. The same goes for phrases such as "(a + +) - (a ++)", etc.
It is important to emphasize that the rule prohibiting use of the term in which the variable over which the
applied side effect occurs more than once a true no exception. Let's look, for example, the expression
"(A + +) * (a ++)". Some, for example, variable "a" has a value of 5th One might think that the result
this expression had to be 30, whatever the order made his calculation, given that
multiplication commutative operations (5 * 6 = 6 * 5). What is certain is that the value podizraza "A + +"
value of variable "a" before writing (ie, 5), and that it leads to increase in value
variable "a" for 1 However, the standards of C and C + + only say that the variable "a" to be
increased before it completes the whole phrase, but do not guarantee that the variable "a" to be increased
immediately after calculating podizraza "A + +". In other words, the compiler has the full right to both
podizraza "A + +" use the old value of variable "a", and that only at the end of the whole phrase completes two
increase. With such a scenario, the value of this term will be 25! Therefore, every term in several places
contains a variable over which is carried out according to standard side effect is considered undefined, and this policy
must be strictly respected. It is also important that even if you work always with the same compiler, you can not
to rely on it to test how the compiler behaves in an example and then conclude that
always so behave. Namely, the compiler has the full right to, depending on the circumstances and environment chooses
podizraza order calculations, which therefore may vary from case to case!
Because beginners do have a tendency to carelessly experimenting with side effects,
will be useful to emphasize a few illegal, and apparently correct structures. Consider, for
For example, a command like the following:
court <<a + + <<a + +;
This command is also not legal. Actually, this whole statement is really just an expression, and it is
variable "and" over which is applied side effect occurs in two places. Some might be surprised
Why is this term is illegal since it is strictly defined order in print from left to right. According to this
requirements for a hasty conclusion that if, say, the initial value of variable "a" is equal to 5,
The above command should print the values of 5 and 6 However, you must be so. Order print really
is strictly defined from left to right, but the order of printing is not the same as the order of calculation, which
is not strictly defined. Indeed, Consider for example an expression like "court <<x <<y" where "x" and "y"
again an expression. How to interpret this phrase as "(court <<x) <<y", it actually guarantees that the
the expression "x" must print before the term "y", considering that the first must be made podizraz "court <<x" which
prints the word "x" to be the result of his "court" used to print the term "y". However, this does not mean
that the term "x" must be computed before the phrase "y". It is quite possible that the compiler first calculation expression
"Y", then the expression "x" and that after that print the order calculated value of the expression "x" and "y". If this
happen (and the author of these materials are convinced that this really happens sometimes), printing will be in accordance with
expected. Also, as in the previous example, it may happen that the variable "a" is increased
(Twice) after each print!
For the same reason, we can not rely even on the effects of commands like the following:
court <<(a = 2) <<"" <<(b = 3) <<"" <<a + b;
Regardless of what is sure to be after the execution of this order variable "a" have a value of 2, and
variable "b" value of 3, there is no guarantee that it will produce the expected print "2 3 5.
Namely, it is quite possible that podizraz "a + b" will be calculated before the making of the assignment "a = 2 and
"B = 3", and that it will be a calculated value used for printing, so that the last printed
value will be the 5th In accordance with the rule stated above, the upper term is not legal, given that each
by changing "a" and "b" of giving effect to side effect of the phrase appears twice. In other
words, phrases like the previous no need to write, which is certainly not a problem because the desired effect
we can achieve the sequence of commands like the following:
3
a = 2;
b = 3;
court <<a <<"" <<b <<"" <<a + b;
The paper presents examples clearly indicate that expressions with side effects should be used with caution.
Beginners are advised to avoid the formation of more complex expressions that contain side effects, especially
expressions containing more than one side effect.
The problem with side effects can occur when you call a function (subroutine). Specifically, although
standards of C and C + + guarantees that the actual values of all parameters to be calculated before
what their values are transferred to the formal parameters (ie before execution
subroutine), the languages C and C + + does not prescribe the order in which the actual parameters to be calculated. Although
the order of calculating the actual parameters in most cases does not matter, it may be important in
when the actual parameters are expressions that contain side effects. For example, consider
follows a simple routine that simply prints the value of its formal parameters:
int subroutine (int a, int b) (
court <<a <<"" <<b <<endl;
)
Suppose now that we made the following call:
int x (5);
Subroutine (x + +, x + +);
What will print after the execution of this subroutine! The answer is not mandated standards
C + +, or print can not be predicted! The only thing guaranteed is that each expression "x + +" will be
made, so that at the end of variable "x" certainly be an asset 7th However, it is not defined if
will first be calculated in the left or right expression "x + +". If the first calculation of the left expression in a formal
parameter "a" to be transferred to the value 5 (let's not forget that the value of the expression "x + +" value
variable "x" before the increase), while parameter "b" value of 6, so the print will be "5 6". However,
If you first calculate the right term, you will receive print "6 5". We must not think that the problem arises
solely for the use of two side effects in the same order (which is certainly considered to be illegal). Specifically,
is equally problematic and the following call:
int x (5);
Subroutine (x + +, x);
It is not difficult to check that, depending on the order of execution, you could get a print "5 6" or
"5 5. Similar problems we have in the next call, which could, depending on the order of
calculating the actual parameters can get print "4 6" or "7 4":
int x (5);
Subroutine (x = 4, x + 2);
The problem occurs in the following structures, which often experiment with beginners
C language, which is (or rather, not working) and C + +:
printf ("% d% d", x + +, x + +);
Namely, that "printf" function also, even here there is no guarantee that the two podizraza
"X + +" to be first calculated (before both forward function), so that the final print to the
structures produced is not precisely defined and can depend on how the used compiler, and
the context in which such a command used.
Because of these concerns, the standard of C and C + + is forbidden in some of the actual
parameters of a variable over which is in another real parameter of the same subroutine
perform side effects. This prohibition is not a syntactic nature, so that the compiler allows these calls,
4
but their effect is not predictable. Of course, that standards of C and C + + can regulate the order of
calculating the actual parameters (eg, from left to right). However, the Committee for Standardization
considered that the imposition of unnecessary restrictions to the order of the authors of the compiler, since there
computer architecture in which the calculation from left to right efficiently by calculating the right-
left, while there are computer architecture in which the reverse is true.
Once again it is necessary to emphasize that in no case should try to determine which strategy
using your compiler, so that in future, relying on the established strategy. In the first place, by written
program does not work if you try translate some other compiler. Worse yet, the
standard compilers have the right to choose depending on the circumstances of the order of calculation
parameters. In other words, if you are experimenting to determine the compiler to use
calculated parameters from right to left, does not mean that he does always. In fact, many compilers
I can change my constant order parameter calculations if in a particular situation
conclude that the change in sequence lead to more efficient translation of code!
It is true that the order of evaluation of the arguments of functions are undefined...so in this case you could theoretically get "2 3 randomgarbage". However, for everything else, I believe I am correct.