Expression evaluation order - c++

I recently got confused by the following c++ snippet:
#include <cstdio>
int lol(int *k){
*k +=5;
return *k;
}
int main(int argc, const char *argv[]){
int k = 0;
int w = k + lol(&k);
printf("%d\n", w);
return 0;
}
Take a look at line:
int w = k + lol(&k);
Until now I thought that this expression would be evaluated from left to right: take current value of k (which before calll to lol function is 0) and then add it to the result of lol function. But compiler proves me I'm wrong, the value of w is 10. Even if I switch places to make it
int w = lol(&k) + k;
the result would be still 10. What am I doing wrong?
Tomek

This is because the parameters in an expression are not specified to be evaluated in any particular order.
The compiler is free to execute either parameter k or lol(&k) first. There are no sequence points in that expression. This means that the side-effects of the parameters can be executed in any order.
So in short, it's not specified whether the code prints 5 or 10. Both are valid outputs.
The exception to this is short-circuiting in boolean expressions because && and || are sequence points. (see comments)

This code either yields 5 or 10 depending on the choice of evaluation oder of the function call relative to that of the left side of +.
Its behavior is not undefined because a function call is surrounded by two sequence points.

Plus is by definition commutative, so the order in your example is totally implementation-defined.
Mysticial is right when mentioning sequence points. Citing Wikipedia article (don't have C++ standard at hand):
A sequence point in imperative programming defines any point in a
computer program's execution at which it is guaranteed that all side
effects of previous evaluations will have been performed, and no side
effects from subsequent evaluations have yet been performed. They are
often mentioned in reference to C and C++, because the result of some
expressions can depend on the order of evaluation of their
subexpressions. Adding one or more sequence points is one method of
ensuring a consistent result, because this restricts the possible
orders of evaluation.
The article also has a list of sequence point in C++.

Related

Different Recursion Output under different systems

Consider the following c++ code for a simple binary tree DFS traversal:
#include <iostream>
#include <vector>
using namespace std;
int print_vector(vector<char> *vec){
for (auto &it: *vec)
cout<<it;
cout<<'\n';
return 0;
}
int btree_dfs_traversal(int max_depth, int cur_depth, vector<char> position){
if (cur_depth>max_depth)
return 0;
print_vector(&position);
vector<char>left = position;
vector<char>right = position;
left.push_back('l');
right.push_back('r');
return btree_dfs_traversal(max_depth, cur_depth+1, left)+btree_dfs_traversal(max_depth, cur_depth+1, right);
}
int main(int argc, const char * argv[]) {
vector<char> pos;
btree_dfs_traversal(4, 0, pos);
return 0;
}
The function(a minimal example) visits a binary tree, and prints the "position" of each node it visits. The only difference with a standard DFS is that (this part made the difference), most implementation uses a iteration for visiting the two nodes, while my the return statement returns the sum of two visits.
I expected the program to recurse from the left statement, i.e. the output starts with l, ll, lll, ... And indeed in my system(OSX) it is like this, and ideone has this output too.
However, in some friends' system, the output is different. The recursion starts from the right statement, i.e. r, rr... Unfortunately, I do not have exact information of their complier information at present.
My question is: is the sum of two recursion being a undefined behavior such that different compiler can produce different results? Or, it is just wrong to start from right?
The "problem" is that in f(1) + f(2) it is unspecified which function call comes first. Different compilers will pick different order and the order can depend on any number of unrelated factors. From the C++ reference:
Order of evaluation
Order of evaluation of the operands of almost all C++ operators (including the order of evaluation of function arguments in a function-call expression and the order of evaluation of the subexpressions within any expression) is unspecified. The compiler can evaluate operands in any order, and may choose another order when the same expression is evaluated again.
There are exceptions to this rule which are noted below.
Except where noted below, there is no concept of left-to-right or right-to-left evaluation in C++. This is not to be confused with left-to-right and right-to-left associativity of operators: the expression f1() + f2() + f3() is parsed as (f1() + f2()) + f3() due to left-to-right associativity of operator+, but the function call to f3 may be evaluated first, last, or between f1() or f2() at run time.
See http://en.cppreference.com/w/cpp/language/eval_order for exceptions and more info.

c++ spaces in operators , what are the rules

Does spaces have any meaning in these expressions:
assume:
int a = 1;
int b = 2;
1)
int c = a++ +b;
Or,
2)
int c = a+ ++b;
When I run these two in visual studio, I get different results. Is that the correct behavior, and what does the spec says?
In general, what should be evaluated first, post-increment or pre-increment?
Edit: I should say that
c =a+++b;
Does not compile on visual studio. But I think it should. The postfix++ seems to be evaluated first.
Is that the correct behavior
Yes, it is.
Postfix ++ first returns the current value, then increments it. so int c = a++ +b means compute the value of c as the sum between current a(take the current a value, and only after taking it, increment a) and b;
Prefix ++ first increments the current value, then returns the value already incremented, so in this case, int c = a+ ++b means compute c as the sum between a and the return of the next expression, ++b, which means b is first incremented, then returned.
In general, what should be evaluated first, post-increment or
pre-increment?
In this example, it is not about which gets evaluated first, it is about what each does - postfix first returns the value, then increments it; prefix first increments the value, then returns it.
Hth
Maybe it helps to understand the general architecture of how programs are parsed.
In a nutshell, there are two stages to parsing a program (C++ or others): lexer and parser.
The lexer takes the text input and maps it to a sequence of symbols. This is when spaces are handled because they tell where the symbols are. Spaces really matter at some places (like between int and c, to not confuse with the symbol intc) but not others (like between a and ++ because there is no ambiguity to separate them).
The first example:
int c = a++ +b;
gives the following symbols, each on its own row (implementations may do this in slightly different ways of course):
int
c
=
a
++
+
b
;
While in the other case:
int c = a+ ++b;
the symbols are instead:
int
c
=
a
+
++
b
;
The parser then builds a tree (Abstract Syntax Tree, AST) out of the symbols and according to some grammar. In particular, according to the C++ grammar, + as an addition has a lower precedence than the unary ++ operator (regardless of postfix or prefix). This means that the first example is semantically the same as (a++) + b while the second is like a+ (++b).
For your examples, the ASTs will be different, because the spaces already lead to a different output at the lexer phase.
Note that spaces are not required between ++ and +, so a+++b would theoretically be fine, but this is not recommended for readability. So, some spaces are important for technical reasons while others are important for us users to read the code.
Yes they should be different; the behaviour is correct.
There are a few possible sources for your confusion.
This question is not about "spaces in operators". You have different operators. If you were to remove the space, you would have a different question. See What is i+++ increment in c++
It's also not about "what should be evaluated first, post-increment or pre-increment". It's about understanding the difference between post-increment and pre-increment.
Both increment the variable to which they apply.
But the post-increment expression returns the value from before the increment.
Whereas the pre-increment expression returns the value after the increment.
I.e.
//Given:
int a = 1;
int b = 2;
//Post-increment
int c = a++ +b; =>
1 + 2; (and a == 2) =>
3;
//Pre-increment
int c = a+ ++b; =>
1 + 3; (and b == 3) =>
4;
Another thing that might be causing confusion. You wrote: a++ +b;. And you may be assuming that +b is the unary + operator. This would be an incorrect assumption because you have both left and right operands making that + a binary additive operator (as in x + y).
Final possible confusion. You may be wondering why:
in a++ +b the ++ is a post-increment operator applied to a.
whereas in a+ ++b it's a pre-increment operator applied to b.
The reason is that ++ has higher precedence than the binary additive +. And in both cases it would be impossible to apply ++ to +.

What is "from ?: first" In TextMate Source Code regexp.cc [duplicate]

I was writing a console application that would try to "guess" a number by trial and error, it worked fine and all but it left me wondering about a certain part that I wrote absentmindedly,
The code is:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x,i,a,cc;
for(;;){
scanf("%d",&x);
a=50;
i=100/a;
for(cc=0;;cc++)
{
if(x<a)
{
printf("%d was too big\n",a);
a=a-((100/(i<<=1))?:1);
}
else if (x>a)
{
printf("%d was too small\n",a);
a=a+((100/(i<<=1))?:1);
}
else
{
printf("%d was the right number\n-----------------%d---------------------\n",a,cc);
break;
}
}
}
return 0;
}
More specifically the part that confused me is
a=a+((100/(i<<=1))?:1);
//Code, code
a=a-((100/(i<<=1))?:1);
I used ((100/(i<<=1))?:1) to make sure that if 100/(i<<=1) returned 0 (or false) the whole expression would evaluate to 1 ((100/(i<<=1))?:***1***), and I left the part of the conditional that would work if it was true empty ((100/(i<<=1))? _this space_ :1), it seems to work correctly but is there any risk in leaving that part of the conditional empty?
This is a GNU C extension (see ?: wikipedia entry), so for portability you should explicitly state the second operand.
In the 'true' case, it is returning the result of the conditional.
The following statements are almost equivalent:
a = x ?: y;
a = x ? x : y;
The only difference is in the first statement, x is always evaluated once, whereas in the second, x will be evaluated twice if it is true. So the only difference is when evaluating x has side effects.
Either way, I'd consider this a subtle use of the syntax... and if you have any empathy for those maintaining your code, you should explicitly state the operand. :)
On the other hand, it's a nice little trick for a common use case.
This is a GCC extension to the C language. When nothing appears between ?:, then the value of the comparison is used in the true case.
The middle operand in a conditional expression may be omitted. Then if the first operand is nonzero, its value is the value of the conditional expression.
Therefore, the expression
    x ? : y
has the value of x if that is nonzero; otherwise, the value of y.
This example is perfectly equivalent to
    x ? x : y
In this simple case, the ability to omit the middle operand is not especially useful. When it becomes useful is when the first operand does, or may (if it is a macro argument), contain a side effect. Then repeating the operand in the middle would perform the side effect twice. Omitting the middle operand uses the value already computed without the undesirable effects of recomputing it.

C/C++ Math Order of Operation

So I know that C++ has an Operator Precedence and that
int x = ++i + i++;
is undefined because pre++ and post++ are at the same level and thus there is no way to tell which one will get calculated first. But what I was wondering is if
int i = 1/2/3;
is undefined. The reason I ask is because there are multiple ways to look at that (1/2)/3 OR 1/(2/3).
My guess is that it is a undefined behavior but I would like to confirm it.
If you look at the C++ operator precedence and associativity, you'll see that the division operator is Left-to-right associative, which means this will be evaluated as (1/2)/3, since:
Operators that are in the same cell (there may be several rows of operators listed in a cell) are evaluated with the same precedence, in the given direction. For example, the expression a=b=c is parsed as a=(b=c), and not as (a=b)=c because of right-to-left associativity.
In your example the compiler is free to evaluate "1" "2" and "3" in any order it likes, and then apply the divisions left to right.
It's the same for the i++ + i++ example. It can evaluate the i++'s in any order and that's where the problem lies.
It's not that the function's precedence isn't defined, it's that the order of evaluation of its arguments is.
The first code snippet is undefined behaviour because variable i is being modified multiple times inbetween sequence points.
The second code snippet is defined behaviour and is equivalent to:
int i = (1 / 2) / 3;
as operator / has left-to-right associativity.
It is defined, it goes from left to right:
#include <iostream>
using namespace std;
int main (int argc, char *argv[]) {
int i = 16/2/2/2;
cout<<i<<endl;
return 0;
}
print "2" instead of 1 or 16.
It might be saying that it is undefined because you have chosen an int, which is the set of whole numbers.
Try a double or float which include fractions.

cout vs printf -- order of execution [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Compilers and argument order of evaluation in C++
cout << order of call to functions it prints?
This:
int k=3;
printf("%d %d %d",k++,k,++k);
Gives output as 4 4 4 because they are pushed into the stack as:
%d%d%d
4 -- for k++
4 --for k
4 --for ++k
Right?
This:
int k = 3;
cout << k++ << k << ++k;
Is actually repeated function calls, so it's equivalent to:
( ( (cout << k++) << k) << ++k);
So, I suppose first of all k++ then k and then ++k must always be executed in this order, right? I believe a function call is a sequence point, but the outputs vary on different implementations. Why is this so?
The order of evaluation of arguments is unspecified by the standards. That means, it can happen in any order the implementation wants to.
This is undefined because there is no sequence point between the , in the printf statement. Without a sequence point the compiler is free to order writes to the memory location k as it wills.
Now you may be wondering 'what the hell is a seqeunce point' and why is it relevant? Basically a sequence point is a point in the code where the memory location in question, in this case k has been modified at most once. There is a fuller description here:https://isocpp.org/wiki/faq/misc-technical-issues#double-mod-betw-seq-pt
As you can see from the FAQ, the , in the printf does not introduce a sequence point.
In the case of cout this is different because there are 3 function calls to operator >>. A function call introduces a sequence point therefore the modifications to memory location k have a defined order. However (and this was a point I missed but Cubbi pointed out) because C/C++ doesn't define the order of evaluation of function arguments those arguments, even if they are functions, can be evaluated in any order the compiler defines. So in the expression:
f(h(), g())
Whether h() or g() is evaluated first is undefined: http://www.stroustrup.com/bs_faq2.html#undefined. So this is the reason why even in the case of cout you are getting different results from different compilers, basically because the cout << k++ << k << ++k translates to cout.operator<<(k++).operator<<(k).operator(++k) which is effectively an expression like this: f(h(g(cout, k++), k), ++k) and each function argument is evaluated in an unspecified order.
You've got answers that cover the call to printf but you're also asking why does the output of the cout statement vary between compilers.
You're correct to say that it is equivalent to
( ( (cout<<k++)<<k)<<++k);
now, to evaluate that expression and obtain its result, the compiler must evaluate the rightmost <<. Before the function call to that << can be made, its two operands, ( (cout<<k++)<<k) and ++k must be evaluated. And those two evaluations can occur in any order, or even simultaneously (compilers often interleave cpu instructions from two independent (as the compiler thinks) branches of code.
And since the evaluation of both expressions involves writing to k, the behavior is undefined in case of the cout as well.
Actually, both printf and cout << are function calls, and C++ as well as C do not define an evaluation order for arguments. So the result for these test cases would vary from compiler to compiler, since its implementation defined.