Turbo C++ (not visual)(Postfix and prefix operators) - c++

When I run this program I get output as 2
#include<iostream.h>
#include<conio.h>
void main(){
clrscr();
int a = 10;
int c = a-- - --a;
cout<<c;
getch();
}
... but when I just modify it to
#include<iostream.h>
#include<conio.h>
void main(){
clrscr();
int a = 10,c;
c = a-- - --a;
cout<<c;
getch();
}
... I get output 0. WHY? In java both the of them gave output as 2. Whats wrong with C++?
Explain :(

Nothing wrong with C++, but there's something wrong in how you're using it.
The expression a-- - --a has undefined behavior in C++, and anything can happen.
The cleanest solution is to not write code like that (I wouldn't do it even if it were legal).

To elaborate a bit on Luchian's answer. In C++, the order in which sub-expressions are evaluated inside an expression is not specified. This means that in the following expression:
int c = a-- - --a;
there are two equally valid evaluation orders.
Evaluate a-- first (returns 10), then --a (returns 8), then
substract (returns 2).
Evaluate --a first (returns 9), then
a-- (returns 9), then substract (returns 0).
This is meant to improve optimisation oportunities for compilers. Naturally, this means that in C++ it is a mistake to use expressions that depend on evaluation order, because there is no way to know which order the compiler will select. The trade-off between efficiency and error avoidance is different in C++ and in Java.

Related

A C++ program. Why does this code work?

int main()
{
int a=1;
int b=2;
int c=a+++b;
cout<<"c"<<c<<endl;
}
c's value turns out to be 3. While, it gives me an error for c=a++b. What is happening here? Why does c=a+++b work?
A key part of why a+++b "works", and a++b doesn't is the way the C and C++ language parsing is defined. It is what is called a 'greedy' parser. It will combine as many elements as possible to produce a valid token.
So, given that it's a greedy parser, a++b becomes a++ b, which is not valid. a+++b becomes a++ + b, which is syntactically valid - whether that is what you WANT is another matter. If you want to write a + +b, then you need spaces to separate the tokens.
Have a look at the C++ operator precedence.
(++) post-increment has the highest precedence, sou you end up with (a++) + b.
Looks like a is post increment then added to b with bad spacing. For example a++ + b. The variable a is evaluated then incremented. That being said a++b is invalid syntax.

Variable initialization with itself

Is it safe to write such code?
#include <iostream>
int main()
{
int x = x-x;// always 0
int y = (y)? y/y : --y/y // always 1
}
I know there is undefined behaviour, but isn't it in this case just a trash value? If it is, then same value minus same is always 0, and same value divided by itself (excluding 0) is always 1. It's a great deal if one doesn't want to use integer literals, isn't it? (to feint the enemy)
Allow me to demonstrate the evil magic of undefined behaviour:
given:
#include <iostream>
int main()
{
using namespace std;
int x = x-x;// always 0
int y = (y)? y/y : --y/y; // always 1
cout << x << ", " << y << endl;
return 0;
}
apple clang, compile with -O3:
output:
1439098744, 0
Undefined is undefined. The comments in the above code are lies which will confound future maintainers of your random number generator ;-)
I know there is undefined behaviour, but isn't it in this case just a trash value? If it is, then same value minus same is always 0, and same value divided by itself (excluding 0) is always 1.
No! No, no, no!
The "trash value" is an "indeterminate value".
Subtracting an indeterminate value from itself does not yield zero: it causes your program to have undefined behaviour ([C++14: 8.5/12]).
You cannot rely on the normal rules of arithmetic to "cancel out" undefined behaviour.
Your program could travel back in time and spoil Game of Thrones/The Force Awakens/Supergirl for everyone. Please don't do this!
Undefined behavior is undefined. Always. Stuff may work or break more or less reliably on certain platforms, but in general, you can not rely on this program not crashing or any variable having a certain value.
Undefined behavior is undefined behavior. There's no "isn't it in this case something specific" (unless you are actually talking about result of a completed compilation, and looking at the generated machine code, but that is no longer C++). Compiler is allowed to do whatever it pleases.

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.

Expression evaluation order

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++.

Does postfix increment perform increment not on returned value?

Again, a silly question.
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
int i = 0;
i = i++;
cout<<i;
return 0;
}
I get 1 printed as a result of this program though I expected 0: first a temp object created eing equal 0, then i is incremented, then temp object is returned and assigned to i. Just according to:
5.2.6 Increment and decrement [expr.post.incr]
1 The value obtained
by applying a postfix ++ is the value
that the operand had before applying
the operator. [Note: the value
obtained is a copy of the original
value ]
I checked it under MS VC 2008 and GCC. They give both the same result, though at least gcc issues a warning in incrementation string. Where am I wrong?
The behavior of
i = i++;
is undefined. If a single expression assigns two different values to a variable, the C++ spec says that anything can happen - it could take on its old value, one of the two new values, or pretty much anything at all. The reason for this is that it allows the compiler to make much more aggressive optimizations of simple expressions. The compiler could rearrange the order in which the assignment and ++ are executed, for example, if it thought it were more efficient.