main(){
int x = 256, y = 4;
printf("%d\n\n", x++ + ++y); //output = 261
printf("%d\n\n", x); // output = 257
printf("%d", y); // output = 5
}
Is the final answer 261, because 256 -> 257 (post operator) and 5 -> 5 (pre operator) cause 256 + 5 = 261?
Given:
int x = 256, y = 4;
printf("%d\n\n", x++ + ++y);
In short: The x++ returns the value 256 and then increments x to 257. The ++y increments y to 5 and returns the value 5. The addition, therefore, adds 256 and 5 yielding 261.
Long windedly: The x++ evaluates to the current value of x which is 256 and schedules an increment of x to 257. Similarly ++y schedules the increment of y to 5 and evaluates to the incremented value 5. The addition, therefore, adds 256 and 5 yielding 261. The order in which the terms involving x and y are evaluated is not defined, but both have to be evaluated before the addition (though the increments may not be complete when the addition is evaluated). Because there is a 'sequence point' when the arguments (and the expression denoting the function) have been evaluated but before the function is called, the increments must be complete when printf() is called.
The next two statements print x and y as 257 and 5.
Note that those two printf() operations could be combined into one. Neither could be combined with the first without invoking undefined behaviour. (See Multiple increments and undefined behaviour for more information on this topic.)
So, allowing for the fact that I would not express it quite the way you wrote it, you seem to have the correct explanation.
Also, Standard C has required a return type on all functions for over 15 years now (since C99 was standardized). You should write:
int main(void)
for a main() function that takes no arguments. (See What should main() return in C and C++? for the full details.)
Note that this question only invokes fully defined behaviour (at least, in the printf() statements). It is not asking about multiple increments on a single variable between sequence points.
It will show UNSPECIFIED behavior
In your case, we can't tell whether x++ will be evaluated first or ++y will be evaluated first. It is compiler dependent.
So don't use expressions involving a combination of post-increment or pre-increment operators in C or C++.
For more information refer to the link:
https://www.quora.com/What-does-an-expression-involving-multiple-post-pre-decrement-increment-operators-evaluate-to-in-C-and-C++#
Related
This question already has answers here:
What is the difference between prefix and postfix operators?
(13 answers)
Closed 11 months ago.
When I was doing the practice questions today, I found that the outputs of printf("%d\n",x--); and printf("%d\n",x); are the same.
I changed it to printf("%d\n",x++); and found to be the same. I want to know why.
#include<stdio.h>
int main()
{
int x;
scanf_s(" %d", &x);
if (x++ > 5)
printf("%d",x);
else
printf("%d\n",x--);
return 0;
}
You used the post-decrement/-increment operators.
x-- decrements x and returns the original value of x.
x++ increments x and returns the original value of x.
To get the desired behaviour, use the pre-decrement/-increment operators.
--x decrements x and returns the modified x.
++x increments x and returns the modified x.
That's simple and you can understand as well if you know the usage of these 2 kind of operators.
Post Increment/Decrement Operator e.g. a++, a-- etc.
So when we use it in the statement, the current value of the variable will be used and post that its value is incremented by 1.
Just take a look into my comments at end of statements (shows the o/p).
#include<stdio.h>
int main()
{
int x;
scanf_s(" %d", &x); // 10
printf("%d", x++); // 10
printf("%d", x); // 11
return 0;
}
Pre Increment/Decrement Operator, e.g. ++a, --a etc.
So when we use it in the statement, first its value of variable is incremented by 1 & then the incremented value will be used.
#include<stdio.h>
int main()
{
int x;
scanf_s(" %d", &x); // 10
printf("%d", ++x); // 11
printf("%d", x); // 11
return 0;
}
I think, now it's clear to you. For info on usages, just take a look into Usage of Pre/Post Increment & Decrement operators in C.
According to the C Standard (6.5.2.4 Postfix increment and decrement operators)
2 The result of the postfix ++ operator is the value of the
operand. As a side effect, the value of the operand object is
incremented (that is, the value 1 of the appropriate type is added to
it)
and
3 The postfix -- operator is analogous to the postfix ++ operator,
except that the value of the operand is decremented (that is, the
value 1 of the appropriate type is subtracted from it).
Consider this pair of calls of printf
int x = 10;
printf( "%d\n", x++ );
printf( "%d\n", x );
The output is
10
11
That is the value of the expression of x++ is the value of its operand that is equal to 10. As a side effect the variable x is increased and in the second call of printf the new value of x after applying the side effect is outputted.
You can imagine this call
printf( "%d\n", x++ );
like
printf( "%d\n", x ), x += 1;
Opposite to postfix increment and decrement operators the values of unary increment (++x) and decrement (--x) operators are values after incrementing and decrementing their operands.
From the C Standard (6.5.3.1 Prefix increment and decrement operators)
2 The value of the operand of the prefix ++ operator is incremented.
The result is the new value of the operand after incrementation.
and
3 The prefix -- operator is analogous to the prefix ++ operator,
except that the value of the operand is decremented.
I'm new to C language and I'm not entirely sure why on Line 4 when post-increment is done the value of x isn't change what I mean is that
x = printf("%d",x++);
The value for x was 12 so the printf would print 12 and then x should be assigned 2 and while ++ was there x should be later changed with 2+1 and on line 6 pre-increment is done so output shouldn't be 124.
Why x on line 4 isn't added?
Please help.
#include <stdio.h>
int main(){
int x = 12;
x = printf("%d", x++);
printf("%d", ++x);
return 0;
}
Make yourself aware of sequence point. From this [emphasis mine]:
There is a sequence point after the evaluation of all function arguments and of the function designator, and before the actual function call.
From this [emphasis mine]:
Increment operators initiate the side-effect of adding the value 1 of appropriate type to the operand. Decrement operators initiate the side-effect of subtracting the value 1 of appropriate type from the operand. As with any other side-effects, these operations complete at or before the next sequence point.
Looks at this statement:
x = printf("%d", x++);
The post increment operator increase the value of operand by 1 but the value of the expression is the operand's original value prior to the increment operation.
So, the value of x passed to printf() will be its original value which is 12 and due to sequence point, before calling printf() the value of x will be incremented by 1. The return value of printf() will be assigned to x which overwrites the last value of x which is the incremented value due to post ++ operator. Hence, after this statement the value of x is 2.
The value for x was 12 so the printf would print 12 and then x should be assigned 2 and while ++ was there x should be later changed with 2+1 and on line 6 pre-increment is done so output shouldn't be 124.
no, the assignment is done after all concerning printf("%d", ++x);, your code is equivalent to that :
#include <stdio.h>
int main(){
int x = 12;
int y = printf("%d", x++);
x = y;
printf("%d", ++x);
return 0;
}
so x = printf("%d", ++x); does :
printf writes 12
then x is incremented to value 13
then x is assigned to the result of printf valuing 2
then you execute printf("%d", ++x); while x values 2 before, so x is incremented before to be given in argument, so 3 is written
and the final print result is 123
PS. As said by #H.S. in an other remark :There is a sequence point after the evaluation of all function arguments (x++ is an argument to printf()) and the pre/post increment/decrement operation complete at or before the next sequence point.
This will work for you:
++x is prefix increment and the x++ is postfix increment, and here is the difference on both of them:
The prefix increment returns the value of a variable after it has been incremented.
On the other hand, the more commonly used postfix increment returns the value of a variable before it has been incremented.
#include <stdio.h>
int main()
{
int x = 12;
x = printf("%d", ++x);
printf("%d", ++x);
return 0;
}
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 6 years ago.
testing some code when studying C language,
#include <stdio.h>
#include <math.h>
#define hypotenusa(x, y) sqrt((x) * (x) + (y) * (y))
int main(void) {
int a, x;
x = 2;
a = hypotenusa(++x, ++x);
printf("%d\n", a);
}
And I am getting the answer
6 in one program(dosbox gcc compiler)
7 in codelight gcc compiler and
8 on codeChef online compiler
can anyone explain this behaviour?
my logic says it should be 6 (sqrt(42)) but...
It's undefined behaviour.
After the macro replacement
a = hypotenusa(++x, ++x);
becomes:
a = sqrt((++x) * (++x) + (++x) * (++x));
As you can see x is modified multiple times without any intervening sequence point(s). See What Every C Programmer Should Know About Undefined Behavior.
hypotenusa(++x, ++x) is undefined behavior.
It is up to the compiler which of the parameters gets incremented (and pushed) first - after the macro expansion, there are a total of four instances, and the sequence is not defined.
You should never increment the same variable multiple times in the same statement, to avoid this kind of issues. Using a variable twice in a macro can hide this error and make it really nasty.
The behavior of your macro is undefined, meaning any result is possible.
Chapter and verse
6.5 Expressions
...
2 If a side effect on a scalar object is unsequenced relative to either a different side effect
on the same scalar object or a value computation using the value of the same scalar
object,
the behavior is undefined. If there are multiple allowable orderings of the
subexpressions
of an expression, the behavior is undefined if such an unsequenced side
effect occurs in any
of the orderings.84)
84) This paragraph renders undefined statement expressions such as i = ++i + 1;
a[i++] = i;
while allowing i = i + 1;
a[i] = i;
Basically, if you modify the value of an object more than once in an expression, or both modify an object and use its value in a computation in an expression, the result will not be well-defined unless there is a sequence point in between those operations. With a few exceptions, C does not force left-to-right evaluation of expressions or function parameter evaluations, nor does it mandate that the side effect of ++ or -- be applied immediately after evaluation. Thus, the result of an expression like x++ * x++ will vary from platform to platform, program to program, or even potentially from run to run (although I've never seen that in practice).
For example, given the expression y = x++ * x++, the following evaluation sequence is possible:
t0 <- x // right hand x++, t0 == 2
t1 <- x // left hand x++, t1 == 2
y <- t0 * t1 // y = 2 * 2 == 4
x <- x + 1 // x == 3
x <- x + 1 // x == 4
which doesn't give you the result you expect if you assume left-to-right evaluation.
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 9 years ago.
I'm currently learning C, and my teacher gave us some homework. We had to identify the output of some code. I don't understand how y=4.
The code is as follows
int main() {
int w = 3, y = 3;
printf("w = %i\n", --w + w--);
printf("y = %i\n\n", y = w + y++);
return 0;
}
The behaviour is undefined since you modify the value of a variable twice between two sequence points.
You should read more about sequence points http://en.wikipedia.org/wiki/Sequence_point .This is what the Standard says about it:
At certain specified points in the execution sequence called sequence points, all side effects of previous evaluations shall be complete and no side effects of subsequent evaluations shall have taken place.
Let me preface this with an important public service announcement:
When your compiler gives you a warning, any warning, you would do well to pay attention to it. The code example in your question gives rise to Undefined Behavior - in other words, the C standard does not guarantee that every compiler will give the same results, given your code. That is Always a Bad Thing.
With that out of the way, here is an explanation of what is going on.
I modified your code slightly to look at the intermediate value of w:
#include <stdio.h>
int main(void) {
int w = 3, y = 3;
printf("w = %i\n", --w + w--);
printf("w is actually %d\n", w);
printf("y = %i\n\n", y = w + y++);
return 0;
}
My compiler complains about this code with the following warnings:
order.c:6:24: warning: multiple unsequenced modifications to 'w' [-Wunsequenced]
printf("w = %i\n", --w + w--);
^ ~~
order.c:8:35: warning: multiple unsequenced modifications to 'y' [-Wunsequenced]
printf("y = %i\n\n", y = w + y++);
~ ^
2 warnings generated.
And the output is
w = 4
w is actually 1
y = 4
What is happening? Since compilers parse the statement left-to-right, the statement
--w + w--
seems to result in the following steps (for my compiler):
--w : decrement w, it is now 2
w-- : use the value of '2', but decrement w when you are done
The result is that the sum is 2+2 and the first line prints 4, but after the sum is evaluated w is decremented to 1. However you cannot rely on this behavior - which is why the compiler threw a warning. As Eric Postpischil pointed out there may be situations where the order of execution might be different. "Don't do it" is the bottom line - you are courting Undefined Behavior.
Note that the fact that your program printed w equals 4 doesn't mean that this was true at any time. As you can see, when you actually print out w it is 1.
Assuming the compiler executed these statements in the above order, we go to the next line:
y = w + y++
We start with w = 1 and y = 3. The sum of these two is 4, and that is the value of the expression
y = w + y++
which is therefore what is printed (4).
As a side effect, y is incremented. As it happens, either way the value of y is 4 at the end. If you change the code so you start with w = 5, you end up with y = 6. In other words, the effect of y++ got overridden by the y = assignment.
Undefined Behavior
There is undefined behavior (as described in Why are these constructs (using ++) undefined behavior?) in this code in (at least) these two parts:
--w + w--
y = w + y++
This means that the results you're getting aren't portable or guaranteed.
Lying Code
On top of the undefined behavior, the output actually lies to you. printf("w = %i\n", --w + w--); looks like it's printing the value of w (in that it prints w = …), but it's not printing the value of w, it's printing the value of --w + w-- (which is undefined, so it's actually printing the value of whatever the compiler compiled --w + w-- to).
So what the value of w?
The code your compiler has generated for --w + w-- has the side effect of making w's value be 1, since it is originally 3, and both --w and w-- decrement w. However, the value of --w + w-- (in the code that your compiler generated is, based on the output that you're getting, 4. What could cause this? Well, --w could be evaluated first, which decrements w from 3 to 2, and returns the new value of w, which is 2. Then w-- could be evaluated, which decrements w from 2 to 1, but returns the original value of w, which is 2. The sum of 2 and 2, of course, is 4.
So, the value of --w + w-- is 4, and the new value of w is 1.
And what happens with y?
w's new value is 1, so when you execute (recalling that the value of y is 3):
printf("y = %i\n\n", y = w + y++);
The side effect of y++ is that y is incremented (but it's undefined whether this happens before or after the assignment), but the value of the expression is the previous value of y, which in this case is 3. Therefore, you're adding w, whose value is 1, and and the value of y++, which is 3. You're then assigning 4 to y, and the value of that assignment is 4, so you get 4 as the output. There's still behavior that might be undefined in y = w + y++ because it's not clear when the increment of y should be happening: before or after the assignment?
Your teacher is assuming a specific order of evaluation which is not guaranteed by the language.
Assuming strict left-to-right evaluation, and assuming that side effects are applied immediately, then given the starting values for w and y, the following things happen:
--w evaluates to w-1 (2), and as a side effect decrements w; w is now 2
w-- evaluates to w (2), and as a side effect decrements w; w is now 1
As a result of 1 and 2, --w + w-- evaluates to 4
y++ evaluates to y, and as a side effect increments y; y is now 4
As a result of 4, w + y++ evaluates to 1 + 3, or 4
As a result of 5, y = w + y++ assigns 4 to y.
BUT...
As I said above, this behavior is not guaranteed by the language; except in a few specific cases, the order of evaluation within an expression is left unspecified, so y being 4 is only one of many possible results, all of which are considered equally correct as far as the langauge is concerned.
The behavior of any expression that takes on the following forms (both ++ and --, both prefix and postfix):
x++ + x++
a[i++] = i
y = y++
is undefined. Similarly, the behavior of statments like
foo(y++, y++);
is also undefined.
Question 1
int x;
if (x++)
{
printf ("\nASCII value of X is smaller than that of x");
}
Is x assigned here with a garbage value ??
Question 2:
main ()
{
int i;
for (i = 0; i++ < 10;)
{
printf ("%d\n", i);
}
}
Can anyone explain how i++ < 10 works?I mean it should end at 9 why 10
The value of x is indeterminate, and is possibly a trap representation, in which case the behavior of x++ is undefined.
The expression i++ evaluates to the current value of i; as a side effect, the value in i is incremented. So if i == 1, the expression i++ will evaluate to 1, and as a side effect i will be set to 2.
Chapter and verse:
6.5.2.4 Postfix increment and decrement operators
...
2 The result of the postfix ++ operator is the value of the operand. After the result is
obtained, the value of the operand is incremented. (That is, the value 1 of the appropriate
type is added to it.) See the discussions of additive operators and compound assignment
for information on constraints, types, and conversions and the effects of operations on
pointers. The side effect of updating the stored value of the operand shall occur between
the previous and the next sequence point.
Emphasis mine.
In the first question, you declare x
int x;
but you do not assign it, this reserves some memory to hold the value of x, but doesn't initialize it to a known value. That's a really bad thing. Then you read it, increment it, and possibly do something.
if ( x++ ) {
printf ( "\nascii value of X is smaller than that of x" ) ;
}
Since you don't know what it's value was before you read it, it is impossible to make an educated guess as to whether your if statement will print anything.
In your second question (please one question per question), you read the value of i, then increment it, and then do the comparison on the read value. Post increment basically means, "increment the value after I read it" and so the new value will be stored, then the comparison made on the old value, and the printf statement below will print the "current, new" value.
Question 1: Yes
Question 2: Yes. i is incremented by one then compared if it's lesser than 10.