This is a very simple question but even have some doubt in sequence point.
int a[3] = {1,2,4};
printf("%d",++a[1]);
o/p
3
Is this a valid c statement, I am getting output 3, which means it is same as
++(a[1])
But how is this possible as we have a pre-increment operator which has to increment the a first then the dereference has to happen.
Please correct my doubt. How we are getting 3?
Behavior is well defined. Operator [] has higher precedence than prefix ++ operator. Therefore operand a will bind to []. It will be interpreted as
printf("%d", ++(a[1]));
Your parentheses are right, your rationale for what you think should happen obviously wrong.
If you were right, and prefix-increment had higher priority than indexing, you would get a compiler-error for ill-formed code, trying to increment an array.
As-is, there's absolutely no chance for sequencing-errors or the like leading to UB.
That's how pre increment operator works. Its similar to ++count. So here your value at a[1] (as [] has higher precendence than ++) get incremented and then its printed onto the console.
As you can see here: http://en.cppreference.com/w/cpp/language/operator_precedence
The operator [] has a higher precedence then ++
Related
I am a little bit confused about pointer index operator in C. I will try to explain my question with an example:
int array[5] = {1,2,3,4,5};
int *p;
p = array;
p[2]++;
In the fourth line, I know that it increments the second index of array. However, when I see an index operator, I convert it.
For instance, I converted p[2]++ to *(p+2)++. According to the operator precedence table, in the statement of *(p+2)++, the increment and dereferencing operators have the same precedence, but increment takes precedence due to right associativity. Therefore, it becomes *(p+3). Then, this statement cannot change any value and just points third index of array.
Why does p[2]++ increment the second index of the array? What is wrong in my perspective?
p[2]++ is equivalent to (*(p+2))++, not *(p+2)++. You need an extra set of parentheses to maintain the precedence from the original expression.
Without them you've got *(p+2)++ which, as you've noted, is equivalent to *((p+2)++). This has a different meaning from the original expression since it splits up the +2 and the *. They need to be done in the same step since [2] is a single atomic operation.
As already commented p[2]++ can be converted to (*(p+2))++, because p[2] is the element you want to increment.
Think that when incrementing indexes is usually done like p[i++]
In math, if a=b+c,then a*d is not b+c*d but (b+c)*d. Likely, p[2] is not be taken by *(p+2) but (*(p+2)) to avoid any change on precedence.
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 4 years ago.
Consider the following line of code.
int i = 2;
i = i++
The second line of code has been identified as undefined. I know this question has been asked before several times and example being this.
But nowhere could I see the issue of operator precedence being addressed in this issue. It has been clearly mentioned that postfix operator precedes assignment operator.
i = (i++)
So clearly i++ will be evaluated first and this value of i is the assigned to i again.
This looks like this particular undefined behavior is contradicting the precedence rule.
Similar to this is the code:
int i = 2;
i++ * i++;
Here according to operator precedence the code can be written as
int i =2;
(i++) * (i++)
Now we do not know whether the (i++) in LHS or RHS of '*' operator is going to be evaluated first. But either way it is going produce the same result. So how is it undefined?
If we write say:
int p;
p = f1() + f2()
where f1() and f2() are defined functions then obviously it's clear we can't decide whether f1() or f2() is going to be evaluated first as precedence rules does not specify this. But a confusion like this does not seem to arise in the current problem.
Please explain.
I do not understand why this question got a negative vote. I needed a clarity between operator precedence and UB and I have seen no other question addressing it.
What you're looking for is in section 6.5 on Expressions, paragraph 3 of the C standard:
The grouping of operators and operands is indicated by the syntax.
Except as specified later, side effects and value computations of
subexpressions are unsequenced.
This means that the side effect of incrementing (or decrementing) via the ++ or -- operators doesn't necessarily happen immediately when the operator is encountered. The only guarantee is that it happens before the next sequence point.
In the case of i = i++;, there is no sequence point in the evaluation of the operands of = nor in the evaluation of postfix ++. So an implementation is free to perform assigning the current value of i to itself and the side effect of incrementing of i in any order. So i could potentially be either 2 or 3 in your example.
This goes back to paragraph 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.
Since i = i++ attempts to update i more than once without a sequence point, it invokes undefined behavior. The result could be 2 or 3, or something else might happen as a result of optimizations for example.
The reason that this is not undefined:
int p;
p = f1() + f2()
Is because a variable is not being updated more than once in a sequence point. It could however be unspecified behavior if both f1 and f2 update the same global variables, since the evaluation order is unspecified.
The problem with using
i = i++
is that the order in which the address of i is accessed to read and write is not specified. As a consequence, at the end of that line, the value of i could be 3 or 2.
When will it be 3?
Evaluate the RHS - 2
Assign it to the LHS. i is now 2.
Increment i. i is now 3.
When will it be 2?
Evaluate the RHS - 2
Increment i. i is now 3.
Assign the result of evaluating the RHS to the LHS. i is now 2.
Of course, if there is a race condition, we don't know what's going to happen.
But nowhere could I see the issue of operator precedence being addressed in this issue.
Operator precedence only affects how expressions are parsed (which operands are grouped with which operators) - it has no effect on how expressions are evaluated. Operator precedence says that a * b + c should be parsed as (a * b) + c, but it doesn't say that either a or b must be evaluated before c.
Now we do not know whether the (i++) in LHS or RHS of '*' operator is going to be evaluated first. But either way it is going produce the same result. So how is it undefined?
Because the side effect of the ++ operator does not have to be applied immediately after evaluation. Side effects may be deferred until the next sequence point, or they may applied before other operations, or sprinkled throughout. So if i is 2, then i++ * i++ may be evaluated as 2 * 2, or 2 * 3, or 3 * 2, or 2 * 4, or 4 * 4, or something else entirely.
OPERATOR PRECEDENCE DOES NOT RESOLVE UNDEFINED EXPRESSION ISSUES.
Sorry for shouting, but people ask about this all the time. I'm afraid I have to say your research on this question must not have been very thorough, if you didn't see this aspect being discussed.
See for example this essay.
The expression i = i++ tries to assign to object i twice. It's therefore undefined. Period. Precedence doesn't save you.
I'm just starting a beginner's guide to games programming tutorial in C. I'm a little confused with the code below.
At main gameOverTick is set to zero, then we have a case when the game is over
case GAME_OVER:
printStatus("GAME OVER!!! The evil DarkLord was defeated");
if (++gameOverTick % 100 == 0){
status = PRINT_GAME_WELCOMESCREEN; // go back to welcome screen
gameOverTick = 0; // reset gameOverTick
}
I would just like to know what role the ++ (pre-inc) operation does on gameOverTick. Does it set gameOverTick to 1 whilst checking the if, or set it to 0 somehow. I know how post-inc ++ works, but this is a new one for me.
Thanks
We've got four answers here and they are all wrong in the same way. Let me make sure this is very clear in your mind: people who tell you that precedence of operators determines the order in which side effects occur as a result of computation of subexpressions are simply wrong. In C, the order in which subexpressions are computed is not controlled by precedence; it is largely undefined. (In C# and Java is is defined not as precedence order but as left-to-right.)
In the specific case here, the value of the ++ operation must be computed before the % happens, but the assignment associated with the ++ operation can happen at any time. In your particular case it doesn't matter when the assignment happens, but it is easy to construct cases where it does matter.
This increases gameOverTick by one before the modulo is calculated and the comparison is done. (A good rule of thumb in C is that unitary operations have tighter binding than binary, and calculations over logic operations.) It guess the purpose of this is to wait 100 loops until it goes hack to the welcome screen, as gameOverTick is only reset if it have gone up to 100.
Most expressions in C have a value; most expressions have a side effect.
Consider the two expressions below
/* a */ i++
/* b */ ++i
The side effect of both expressions is to increase the value of i (that change is only usable after the next sequence point). The value of the first expression is the value i had on the previous sequence point; the value of the second expression is one more than what i had at the previous sequence point.
The code you have written inside parenthesis of if is called an expression, the expression evaluation always follow operator precedence rule, considering the given expression
1.++ operator has highest precedence so '++gameOverTick' is evaluated first as '(gameOverTick = gameOverTick+1)'
2.The next next precedence is for '%' operator so '(gameOverTick+1)%100' is calculated
3.Finally the least precedence operator is '==' hence the obtained result on left side of '==' operator is compared for equality with the right side value.
Example:
-Consider gameOverTick value as 99
-99 is incremented first i.e, 99+1 = 100
-Than the % operation is performed i.e, 100%100 = 0
-Now equality is compared` i.e, 0 == 0 which gives 1
-The evaluation of expression gives 1 hence it is equal to if(1), which indicates a true.
For more on operator precedence you can refer this link
http://www.difranco.net/compsci/C_Operator_Precedence_Table.htm
I would appreciate if you clarify this for me.Here are two recent questions with their accepted answers:
1) What is the difference between *myptr++ and *(myptr++) in C
2) Yet another sequence point query: how does *p++ = getchar() work?
The accepted answer for the first question,concise and easily to understand states that since ++ has higher precedence than *, the increment to the pointer myptr is done first and then it is dereferenced.I even checked that out on the compiler and verified it.
But the accepted answer to the second question posted minutes before has left me confused.
It says in clear terms that in *p++ strictly the old address of p is dereferenced. I have little reason to question the correctness of a top-rated answer of the second question, but frankly I feel it contradicts the first question's answer by user H2CO3.So can anyone explain in plain and simple English what the second question's answer mean and how come *p++ dereferences the old value of p in the second question.Isn't p supposed to be incremented first as ++ has higher precedence?How on earth can the older address be dereferenced in *p++Thanks.
The postfix increment operator does have higher precedence than the dereference operator, but postfix increment on a variable returns the value of that variable prior to incrementing.
*myptr++
Thus the increment operation has higher precedence, but the dereferencing is done on the value returned by the increment, which is the previous value of myptr.
The answer in the first question you've linked to is not wrong, he's answering a different question.
There is no difference between *myptr++ and *(myptr++) because in both cases the increment is done first, and then the previous value of myptr is dereferenced.
The accepted answer for the first question,concise and easily to understand states that since ++ has higher precedence than *,
Right. That is correct.
the increment to the pointer myptr is done first and then it is dereferenced.
It doesn't say that. Precedence determines the grouping of the subexpressions, but not the order of evaluation.
That the precedence of ++ is higher than the precedence of the indirection * says that
*myptr++
is exactly the same (not on the cource code level, of course) as
*(myptr++)
and that means that the indirection is applied to the result of the
myptr++
subexpression, the old value of myptr, whereas (*myptr)++ would apply the increment operator to what myptr points to.
The result of a postfix increment is the old value of the operand, so
*myptr++ = something;
has the same effect as
*myptr = something;
myptr++;
When the side-effect of storing the incremented value of myptr happens is unspecified. It may happen before the indirection is evaluated, or after that, that is up to the compiler.
Section 6.5.2.4 of the C specification discusses the postfix increment and decrement operators. And the second paragraph there pretty much answers your question:
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).
...
The value computation of the result is sequenced before the side effect of
updating the stored value of the operand.
So given *myptr++, yes it's true the the ++ part has higher precedence; but precedence does not exclusively determine your result. The language defines that with the specs. In this case the value of myptr is returned, then the "side effect" of myptr being incremented is executed.
From page 123 of The C Programming Language by K&R:
(p++)->x increments p after accessing x. (This last set of parentheses is unnecessary. Why?)
Why is it unnecessary considering that -> binds stronger than ++?
EDIT: Contrast the given expression with ++p->x, the latter is evaluated as ++(p->x) which would increment x, not p. So in this case parentheses are necessary and we must write (++p)->x if we want to increment p.
The only other possible interpretation is:
p++(->x)
and that doesn't mean anything. It's not even valid. The only possible way to interpret this in a valid way is (p++)->x.
Exactly because -> binds stronger than ++. (it doesn't, thanks #KerrekSB.)
increments p after accessing x.
So first you access x of p, then you increment p. That perfectly matches the order of evaluation of the -> and the + operators.
Edit: aww, these edit's...
So what happens when you write ++p->x is that it could be interpreted either as ++(p->x) or as (++p)->x (which one is actually chosen is just a matter of language design, K&R thought it would be a good idea to make it evaluate as in the first case). The thing is that this ambiguity doesn't exist in the case of p++->x, since it can only be interpreted as (p++)->x. The other alternatives, p(++->x), p(++->)x and p++(->x) are really just syntactically malformed "expressions".
The maximal munch strategy says that p++->x is divided into the following preprocessing tokens:
p then ++ then -> then x
In p++->x expression there are two operators, the postfix ++ operator and the postifx -> operator. Both operators being postfix operators, they have the same precedence and there is no ambiguity in parsing the expression. p++->x is equivalent to (p++)->x.
For ++p->x expression, the situation is different.
In ++p->x, the ++ is not a postfix operator, it is the ++ unary operator. C gives postfix operators higher precedence over all unary operators and this is why ++p->x is actually equivalent to ++(p->x).
EDIT: I changed the first part of the answer as a result of Steve's comment.
Both post-increment and member access operator are postfix expressions and bind the same. Considering that they apply to the primary or postfix expression to the left, there can't be ambiguity.
In
p++->x
The postfix-++ operator can apply only to the expression to the left of it (i.e. to p).
Similarly ->x can only be an access to the expression to its left, which is p++. Writing that expression as (p++) is not needed, but also does no harm.
The "after" in your description of the effects, does not express temporal order of increment and member access. It only expresses that the result of p++ is the value p had before the increment and that that value is the value used for the member access.
The expresion p++ results in a pointer with the value of p. Later on, the ++ part is performed, but for the purposes of interpreting the expression, it may just as well not be there. ->x makes the compiler add the offset for the member x to the original address in p and access that value.
If you change the statement to :
p->x; p++;
it would do exactly the same thing.
The order of precedence is actually exactly the same, as can be seen here - but it doesn't really matter.