This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…)
main()
{
int a=5;
a= a++ + ++a + ++a + a++ + a++;
printf("%d",a);
}
This is not defined.
You can find the Committee Draft from May 6, 2005 of the C-standard here (pdf)
See section 6.5 Expressions:
2 Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.
and the example:
71) This paragraph renders undefined statement expressions such as
i = ++i + 1;
a[i++] = i;
The answer is actually undefined.
Answer in undefined because you've got some situations in which the parser doesn't know how to parse the code..
is a+++b: a + ++b or a++ + b?
Think the fact that usually white space is just ignored when lexing the source code. It may depends upon implementation of the compiler (and some other languages with same ++ operators may choose to give priority to one instead of another) but in general this is not safe.
For example in Java your code line gives 37 as the answer, because it chooses to bind ++ operators in a specific way according to precedence, but it's just a choice..
Related
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 8 years ago.
Today I found something, that made me very anxious about my C++ or basic programming skills. The problem is C++ expression evaluation with post/pre incrementation.
Let's check this, let me say that, trivial example of code:
int a = 5;
int d = a++ + a;
As far as I expected, left and right operands of '=' sign would be calucalted independently, and the final result is (a++) 5 + (a) 5, where post-incremented 'a' has value of 6after 'd' is computed.
But, here's what I got under two popular C compilers:
MinGW: d == 11;
MSVC: d == 10;
Same situation is with:
int a = 5;
int d = a-- + a;
where compilers gave:
MinGW: d == 9; // 5 + 4 , a=4 after 'a--', before '+a'?
MSVC: d == 10; // 5 + 5 , a=4 after 'a-- + a'?
MSVC out is exact as what I expected. Question is what is really happening here? Which compiler is closer to the behaviour defined as standard?
Funny that you should ask about the "behaviour defined as standard"; in fact, both compilers adhere perfectly to the standard, since your programs invoke undefined behaviour.
In a nutshell, the operands to + (and most other binary operators) are unsequenced relative to each other: they can be evaluated in either order, and depending on a particular order (via side effects) invokes undefined behaviour.
With undefined behaviour, of course, a conforming compiler can choose to do anything, legally.
The order of execution for the expression a++ + a is unspecified by the C++ standard, so each compiler is free to evaluate the expression however it wants. Since both are compilers are correct, you need to rewrite your expression into two separate statements to get the particular behavior that you want.
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 8 years ago.
How this code fragment work for array subscription execution direction.
Please explain.
static int a[][2][3]={0,1,2,3,4,5,6,7,8,9,10,11,12};
int i=-1;
int d;
d=a[i++][++i][++i];
printf("%d",d);
This invokes undefined behaviour. Quoting C99 standard §6.5 ¶2
Between the previous and next sequence point an object shall have its
stored value modified at most once by the evaluation of an expression.
Furthermore, the prior value shall be read only to determine the value
to be stored.
There is no sequence point in the evaluation of the array index in
d = a[i++][++i][++i];
Therefore, it's not known when the side effects of evaluation of expressions in [] will take place. Quoting C99 stanadard again §6.5.2.1 ¶2
The definition of the subscript operator [] is that E1[E2] is
identical to (*((E1)+(E2))).
Therefore, the expression a[i++][++i][++i] evaluates to
a[i++][++i][++i]
== *((a[i++][++i]) + (++i))
== *(*((a[i++]) + (++i)) + (++i))
== *(*(*(a + i++) + (++i)) + (++i))
Adding parentheses does not create a sequence point. It only defines the order of evaluation of sub-expressions of the complete expressions. It does not guarantee when the side effects of evaluating the sub-expression will take place.
a[i++][++i][++i]
This statement results in undefined behaviour.
you can try executing code here and you will get different output than 2 that you got. Its not that you will not get output but the behaviour is undefined so you cant predict the output.
This question already has answers here:
Why doesn't a+++++b work?
(9 answers)
Closed 9 years ago.
int i=5;
printf("%d",i+++++i);
This gives error, but:
printf("%d",i+++i);
gives the output 11. In this case, the compiler read it as:
printf("%d",i+ ++i);
Why is this not done in first expression? i.e :
printf("%d",i+++++i);
Because of operator precedence i++++++i is treated as (i++)++ + i). This gives a compiler error because (i++) is not an lvalue.
Modifying the same variable multiple times between two sequence points is an Undefined Behavior according to §6.5 of language specifications
Between the previous and next sequence point an object shall have its stored value
modified at most once by the evaluation of an expression. Furthermore, the prior value
shall be read only to determine the value to be stored.(71)
71) This paragraph renders undefined statement expressions such as
i = ++i + 1;
a[i++] = i;
while allowing
i = i + 1;
a[i] = i;
i+++++i is parsed as i ++ ++ + i. It contains an invalid subexpression i ++ ++. Speaking formally, this expression contains a constraint violation, which is why it does not compile.
Meanwhile i+++i is parsed as i ++ + i (not as i + ++ i as you incorrectly believe). It does not contain any constraint violations. It produces undefined behavior, but is otherwise well-formed.
Also, it is rather naive to believe that printf("%d",i+++i) will print 11. The behavior of i+++i is undefined, meaning that there's no point in trying to predict the output.
In printf("%d",i+++++i);, the source text i+++++i is first processed according to this rule from C 2011 (N1570) 6.4 4:
If the input stream has been parsed into preprocessing tokens up to a given character, the next preprocessing token is the longest sequence of characters that could constitute a preprocessing token…
This causes the lexical analysis to proceed in this way:
i can be a token, but i+ cannot, so i is the next token. This leaves +++++i.
+ and ++ can each be a token, but +++ cannot. Since ++ is the longest sequence that could be a token, it is the next token. This leaves +++i.
For the same reason, ++ is the next token. This leaves +i.
+ can be a token, but +i cannot, so + is the next token. This leaves i.
i can be a token, but i) cannot, so i is the next token.
Thus, the expression is i ++ ++ + i.
Then the grammar rules structure this expression as ((i ++) ++) + i.
When i++ is evaluated, the result is just a value, not an lvalue. Since ++ cannot be applied to a value that is not an lvalue, (i ++) ++ is not allowed.
After the compiler recognizes that the expression is semantically incorrect, it cannot go back and change the lexical analysis. Th C standard specifies that the rules must be followed as described above.
In i+++i, the code violates a separate rule. This is parsed as (i ++) + i. This expression both modifies i (in i ++) and separately accesses it (in the i of + i). This violates C 2011 (1570) 6.5 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.
This rule uses some technical terms: In i ++, the effect of changing i is a side effect of ++. (The main effect is to produce the value of i.) The use of i in + i is a value computation of the scalar object i. And these two things are unsequenced, because the C standard does not specify whether producing the value of i for + i comes before or after changing i in i ++.
This question already has answers here:
3 plus symbols between two variables (like a+++b) in C [duplicate]
(3 answers)
Closed 9 years ago.
In the printf statement i+++j, is it always treated as i++ +j?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main() {
int i =5,j= 6, z;
z=i^j;
printf("%d",i+++j);
return 0;
}
i+++j is equivalent to i++ + j.
This has nothing to do with operator precedence. The +++ is resolved to ++ + by the compiler before expressions are parsed.
The C standard defines a sequence of translation phases, each using as its input the output of the previous one. +++ is resolved to ++ + in phase 3, which decomposes the source into preprocessor tokens. Operator precedence is not considered until phase 7, syntactic and semantic analysis. (The translation phases don't have to be implemented as distinct phases or passes, but the compiler must behave as if they are.)
The rules that says +++ is resolved to ++ + and not + ++ is what's informally called the "maximal munch rule". It's stated in section 6.4 paragraph 4:
If the input stream has been parsed into preprocessing tokens up to a
given character, the next preprocessing token is the longest sequence
of characters that could constitute a preprocessing token.
(Amusingly, the index refers to "maximal munch", but that term isn't mentioned anywhere else in the standard.)
This also implies that i+++++j, which could be tokenized as the valid expression i++ + ++j, is actually i ++ ++ + j, which is a syntax error.
Of course the solution, for a programmer, is to add whitespace to make the division into tokens clear: i++ + j. (i+++j is perfectly clear to the compiler, but i++ + j is much clearer to a human reader.)
Reference: N1570, section 6.4, paragraph 4. N1570 is a draft of the 2011 ISO C standard. This rule is unchanged from earlier versions of the standard. Translation phases are discussed
Yes. It will be parsed as (i++) + (j).
Since postfix increment/decrement operator has higher precedence over the addition operator, there is no doubt it would be treated as (i++) + j.
So, it is not a compiler issue, you should rather consider the operator precedence chart.
Also, I would suggest you to put proper spaces between the expressions, it would be beneficial in case you go through your code later on. :)
Hope that helps!
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 9 years ago.
the answer is coming out to be 45.I cant understand how this thing is working.
main()
{
int a =10;
int i = a++ + ++a + a++ + ++a;
printf("%d , %d ", i,a);
}
Actually the output is an undefined behavior which is fine.
From the C99 standard are 6.5 Expressions, §2
Between the previous and next sequence point an object shall have its
stored value modified at most once by the evaluation of an expression.
Furthermore, the prior value shall be read only to determine the value
to be stored.
The order of evaluation of the operands is unspecified. If an attempt
is made to modify the result of an assignment operator or to access it
after the next sequence point, the behavior is undefined.