This question already has answers here:
Undefined behavior and sequence points
(5 answers)
Closed 8 years ago.
1.macros has always been difficult.
2.Below is the code and output is 125 and 7....Please elaborate the working
#define mul(x) (x++ * ++x * x++)
#include<iostream.h>
void main()
{
int a=4,j;
j=mul(a);
cout<<j<<endl;
cout<<a<<endl;
}
Your program results in undefined behaviour. j could be anything.
Read more here: Undefined behavior and sequence points
What I believe is happening is this.
Set a to 4.
mul is called and a is passed in.
The second multiplication (++x) has the prefix incrementer, so x (a) is increased by 1. a is now 5.
The multiplication now happens. Since the first and last have the postfix incrementer, nothing happens until after the multiplication happens. So we have 5 * 5 * 5 = 125.
Since the multiplication is done now, the postfix incrementers happen which makes x (a) 6 and then 7.
j then equals 125.
???
Profit!
EDIT:
This is explaining the behavior that he is experiencing. I understand that this won't happen in every case.
Related
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 21 days ago.
#include<iostream>
#include<conio.h>
using namespace std;
int main()
{
int y,**p,*pt;
int x=5;
pt=&x;
p=&pt;
y=**p + ++(**p);
cout<<*pt<<" "<<**p<<" "<<x<<" "<<y;
getch();
return(0);
}
output generated 6 6 6 11, why not 6 6 6 12 kindly guide on execution step.
Here my doubt is **p is pointing to x only which is incremented by second operand ++(**p). so value of y should be 12.
This is classic undefined behaviour! There is no guarantee in the C++ standard about the order of evaluation of the operands of the + operator in y=**p + ++(**p).
I tested your code in MSVC and clang-cl and I get the output: 6 6 6 12 - which suggests (as you expect) that ++(**p) is evaluated first. However, on your compiler, it seems that the LHS is evaluated first.
From the cppreference site linked in the comments by Scheff:
Order of evaluation of any part of any expression, including order of
evaluation of function arguments is unspecified (with some exceptions
listed below). The compiler can evaluate operands and other
subexpressions in any order, and may choose another order when the
same expression is evaluated again. There is no concept of
left-to-right or right-to-left evaluation in C++….
PS: Interestingly, changing to y = ++(**p) + **p; also gives 6 6 6 12 as the output.
This question already has answers here:
Undefined behavior and sequence points
(5 answers)
Is the behaviour of i = i++ really undefined?
(9 answers)
Closed 3 years ago.
I am facing problems in understanding the increment orders in C++.
I am aware that increments are unary operators thus they come after parenthesis from right to left.
My question is when do we increase the number?
Here is a simple code:
#include <iostream>
using namespace std;
int main()
{
int a1;
int a(12),b(3);
a1=7+10%3-5;
b=a/b++;
cout<<a1<<"\t"<<b<<endl;
return 0;
}
Here I get a=3 that's right but b=5 , I think it is 3 because we start from the right and increase by 1 then 12/4 gives 3.
Note that the C++ grammar implies that the associativity of the postfix increment is from left to right, and that of the prefix increment is right to left.
The behaviour of b = a / b++; is actually undefined. This is because = is not a sequencing point, so there are simultaneous reads and writes on b.
(The same applies to C.)
It's a variant on i = i++;: for more on that see Is the behaviour of i = i++ really undefined?
This question already has answers here:
Undefined behavior and sequence points
(5 answers)
Closed 4 years ago.
Whats happening x after executing the code below;
int x = 10;
x += x--;
I'm expecting result 19 (adding x to x and then decrease x by 1) but result 20. How does it works behind the curtains? Thank your for your answers.
The behavior in this case was undefined before C++17, see e.g., https://en.cppreference.com/w/cpp/language/eval_order#Undefined_behavior , so if your compiler does not conform to it, it is no use testing or trying to understand it: it will depend on implementation, or even version of the compiler.
If your compiler conforms to C++17, it is guaranteed that in a simple or compound assignment (= or e.g. +=, respectively) all of the side effects of right hand side will be dealt with before evaluating the left hand side.
In your case, x-- is evaluated to be 10 accompanied by setting x=9 as its side effect, then the computer will add 10 to x=9 resulting in x=19.
Thanks to Michał for his correction, which I incorporated into the answer.
Having an older c++ might probably not do the job as the behaviour is literally defined to be undefined, by the older standard. (Thanks to #LightnessRacesinOrbit)
If you just try out an online compiler which will have the latest version, it works just fine and the result is 19 as you expected (x+=x-- is the same as x= x+x--. This means for getting the new "x", it has to sum the old "x"+the old "x" -1. So it will do x+(x--), which is x=10+(9).
Try it out here:
with:
#include <iostream>
using namespace std;
int main()
{
int x = 10;
x += x--;
cout<<x<<endl;
}
This question already has answers here:
Undefined behavior and sequence points
(5 answers)
Closed 6 years ago.
I have a friend who is getting different output than I do for the following program:
int main() {
int x = 20, y = 35;
x = y++ + x++;
y = ++y + ++x;
printf("%d%d", x, y);
return 0;
}
I am using Ubuntu, and have tried using gcc and clang. I get 5693 from both.
My friend is using Visual Studio 2015, and gets 5794.
The answer I get (5693) makes most sense to me, since:
the first line sets x = x + y (which is x = 20+35 = 55) (note: x was incremented, but assigned over top of, so doesn't matter)
y was incremented and is therefore 36
next line increments both, adds the result and sets it as y (which is y = 37 + 56 = 93)
which would be 56 and 93, so the output is 5693
I could see the VS answer making sense if the post-increment happened after the assignment. Is there some spec that makes one of these answers more right than the other? Is it just ambiguous? Should we fire anyone who writes code like this, making the ambiguity irrelevant?
Note: Initially, we only tried with gcc, however clang gives this warning:
coatedmoose#ubuntu:~/playground$ clang++ strange.cpp
strange.cpp:8:16: warning: multiple unsequenced modifications to 'x' [-Wunsequenced]
x = y++ + x++;
~ ^
1 warning generated.
The Clang warning is alluding to a clause in the standard, C++11 and later, that makes it undefined behaviour to execute two unsequenced modifications to the same scalar object. (In earlier versions of the standard the rule was different although similar in spirit.)
So the answer is that the spec makes all possible answers equally valid, including the program crashing; it is indeed inherently ambiguous.
By the way, Visual C++ actually does have somewhat consistent and logical behaviour in such cases, even though the standard does not require it: it performs all pre-increments first, then does arithmetic operations and assignments, and then finally performs all post-increments before moving on to the next statement. If you trace through the code you've given, you'll see that Visual C++'s answer is what you would expect from this procedure.
This question already has answers here:
Undefined behavior and sequence points
(5 answers)
Closed 9 years ago.
What will be the output of code
int a=3,b=4;
++a*=++b;
cout<<a<<endl;
compiler shows a=20 output.How precedence and operator associativity is being used here?
What I understand is:
first b on the left of ++a*=++b; is incremented us its unary operator then comes the
turn of *= so
expression becomes ++a = a * ++b; as a=3 and b=5 now so it becomes 15 then 15 is assigned to a and incremented.Finally getting 16 but compiler gives 20
In your particular case on your particular compiler, it seems that first a is incremented to 4 and b is incremented to 5, then a *= b executes and a becomes 20 (4*5). However other compiler could give different result because it is not a defined behaviour as people mentioned in comments