15

is there any shortcut or bestway to remember the precedence and order of evaluation in C beacause it plays the main role and i or (most of us) usually forgets and end up with the mess. Please Help me....

i want to give an example for this... say..

void main()  
{  
    int a=1;  
    a = a++ + ++a;  
    printf("%d",a);  
}//prints 5; 

void main()  
{  
    int a=1;  
    int x;  
    x = a++ + ++a;  
    printf("%d",x);  
}//prints 4;  

also the expression
x = ++a + a++;
gives a different result

i hope that if post increment have high priority then a++ should be evaluated first please clear me if iam wrong and please explain me how it works..

Gabe
  • 84,912
  • 12
  • 139
  • 238
jack
  • 491
  • 2
  • 7
  • 14

10 Answers10

22

First of all, expressions of the form a++ + ++a, ++a + a++, etc., result in undefined behavior; any result is possible. From the language standard (n1256):

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.72) Furthermore, the prior value shall be read only to determine the value to be stored.73)
...
72) A floating-point status flag is not an object and can be set more than once within an expression.

73) This paragraph renders undefined statement expressions such as
        i = ++i + 1;
        a[i++] = i;
while allowing
        i = i + 1;
        a[i] = i;

So, don't do that.

A well-defined expression like x = a++ + ++b will be parsed as x = ((a++) + (++b)); both forms of the ++ operator have higher precedence than addition, and addition has higher precedence than assignment. The result of the expression will be the same as x = a + (b + 1).

Secondly, remember that the ++ and -- operators have a result and a side effect, as shown below:

Expression          Result         Side effect
----------          ------         -----------
       i++               i            i = i + 1
       ++i           i + 1            i = i + 1
       i--               i            i = i - 1
       --i           i - 1            i = i - 1

Important note to remember: the side effect doesn't have to be applied immediately after the expression is evaluated; it only has to be applied before the next sequence point. It's possible for x = a++ + ++b to be evaluated as follows:

t1 = a;
t2 = b + 1;
x = t1 + t2;
b = b + 1;
a = a + 1;  

In this case, the updates to a and b are deferred until after the addition and assignment to x.

As far as precedence is concerned, here is the general order from high to low:

  1. Postfix operators (all have the same precedence, so sequences of operators will be evaluated left-to-right)
    • array subscript operator []
    • function call operator ()
    • component selection operators . and ->
    • postfix ++ and --
  2. Unary operators (all have the same precedence, so sequences of operators will be evaluated left-to-right)
    • prefix ++ and --
    • sizeof
    • bitwise negation operator ~
    • logical negation operator !
    • unary sign operators - and +
    • address-of operator &
    • dereference operator *
  3. Cast expressions ( type name )
  4. Multiplicative operators *, /, %
  5. Additive operators + and -
  6. Shift operators << and >>
  7. Relational operators <, >, <=, >=
  8. Equality operators == and !=
  9. Bitwise AND &
  10. Bitwise XOR ^
  11. Bitwise OR |
  12. Logical AND &&
  13. Logical OR ||
  14. Conditional operator ?:
  15. Assignment operators =, +=. -=, *=, /=, %=, <<=, >>=, &=, ^=, |=
  16. Sequential (comma) operator ,

So, expressions like *x++ are parsed as *(x++), since the postfix ++ has higher precedence than the unary *. Similarly, sizeof x + 1 is parsed as (sizeof x) + 1, since sizeof has higher precedence than addition. An expression like p++->x is parsed as (p++)->x; both postfix ++ and -> operators have the same precedence, so they're parsed from left to right.

This is about as short as shortcuts get; when in doubt, use parentheses.

John Bode
  • 119,563
  • 19
  • 122
  • 198
  • thanks a lot.... great one... how can i add reputations for this ans? – jack Nov 18 '10 at 07:11
  • Thank you, I wasn't finding references that mentioned the casting operator. – Spidey Apr 12 '12 at 18:18
  • @John Bode, Can you please explain how ++a + ++a is evaluated? – Venkatesh Nov 20 '14 at 10:41
  • @Venkatesh: See the first part of my answer; the evaluation is *undefined*. The expression will be parsed as `(++a) + (++a)`; however, it's not guaranteed that the left hand expression will be evaluated before the right hand expression, nor is it guaranteed that the side effect of the `++` operator is applied immediately after evaluation. You will get different results depending on the compiler, compiler settings, even the surrounding code. `++a + ++a` is a coding error, period. – John Bode Nov 20 '14 at 13:52
  • @Venkatesh C langue is greedy to process lexical token that means ++a+++a is equivalent to (++(a ++)) + a, but it is syntax error!error: lvalue required as increment operand fprintf(stdout, "%u\n", ((++a)++)+a); – firo Jan 23 '15 at 13:48
18

There is a shortcut to remember C operator Precedence.

PUMA IS REBL ( spell "REBL" as if "REBEL").

"I" in IS does not represent any operator and used for completion of the sentence.

(Note: all operators with associativity not specified is left to right).

P - Primary

U - Unary

M - Multiplicative

A - Additive

S- Shift

R- Relational

E- Equality

B- BitWise ( & > ^ > |)

L- Logical ( logical && > logical ||)

and the last three operators are

T- Ternary

A- Assignment

C- Comma

(TACO as in (https://en.wikipedia.org/wiki/Taco) T for Ternary, A for assignment and Co for Comma).

for Associativity All except Unary, Assignment and Ternary are Left to Right (AUTO rides in the right, ie Assignment, Unary and Ternary are right to left).

it is advised to see the comments For more information.

bare_metal
  • 1,134
  • 9
  • 20
  • 3
    So, more like PUMA'S REBL TAC (with a puma being a cat and since our cat is a spelling rebel, it writes "cat" backwards). I would love it, if there was a shortcut to remember the " logical && > logical ||" part. – Kaiserludi Feb 15 '17 at 17:50
  • @Kaiserludi Thats an interesting story, TAC is omitted as it didn't fit , but if PUMA is indeed a CAT, then reversing it at the end is not an issue ( esp because it is a spelling rebel according to you :-)). originally I was thinking PUMA as a shoe brand. May be for the bitwise and logical we can think about something funny. – bare_metal Feb 18 '17 at 11:58
  • @Kaiserludi so the story goes like "C" is a CAT and she is a REBEL and her name is PUMA and she likes to play in SAND ( as in 'ampersand' used in 'address of' and '&' and '&&' ) and like to watch the STARS ( * ,** etc). – bare_metal Feb 18 '17 at 12:44
  • Well, actually a spelling rebl, therefor spelling rebl wrong, too, as that is so rebellish. And, yes, a puma is indeed a cat. It's another word for courgar or mountain lion. – Kaiserludi Feb 20 '17 at 11:18
  • if you need a shortcut for Assosiativity then "AUTO rides in the right side", meaning Assignment, Unary and Ternary operators are Right to Left, O is added for completion) – bare_metal Jun 08 '17 at 11:58
  • for logical and bitwise & always the trick is to understand that PUMA likes to play in SAND ( as in ampersand). – bare_metal Jun 08 '17 at 12:01
  • PUMAS REBL (as in all pumas are revolting), and then TAC (as in to tack on or add something to the end) – rapidDev Oct 10 '18 at 23:32
16

Do like the pros: add parentheses when you are unsure. Then you don't have to remember, plus the code will be easier to read.

Johan Kotlinski
  • 25,185
  • 9
  • 78
  • 101
2

To learn operator precedence try this: 1:ARLA means: A-> Arithmetic operator R->Relational operator L->Logical operator A-> Assignment operator 2: BODMAS B=brackets first( (,) ) O=orders(like power and square etc.,) D=division(/) M=multiplication(*) A=addition(+) S=substraction(-)

Pankaj
  • 21
  • 1
2

If you find it confusing then so will anyone reading your code. If in doubt, use brackets to emphasize.

pauljwilliams
  • 19,079
  • 3
  • 51
  • 79
2

I agree with the other post, always try to use parenthesis. But, if you don't want to, here you go, print this out and stick it next to your computer or something.

Wladimir Palant
  • 56,865
  • 12
  • 98
  • 126
Nico Huysamen
  • 10,217
  • 9
  • 62
  • 88
1

Thou shalt not rely on your memory when operator precedence is concerned. Only in obvious cases. Which are - presedence of arithmetic operators, + - * / %. It is also with knowing that ++ and -- have higher precedence than * to be able to read correctly expressions like *p++ = *q++; Bitwise operations have crazy precedence rules. ALWAYS use parentheses for those.

Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
  • 1
    +1 Bitwise operators seem to have the same precedence as their boolean analogues which is why things like `a & mask == 1` have bitten me in the past. – JeremyP Nov 17 '10 at 13:58
1

it is simple calculation When you write int a=1; x= a++ + ++a; Due to prefix increment operator (in ++a) the value of 'a' will become equal to 2 Therefore the current expression is equivalent to x= 2+2; // x=4 As soon as control goes to next line value of a increases by 1 due to postfix operator, now a =3

Now examine this statement int a=1; a= a++ + ++a; In this statement as explained above value of 'a' will be equal to the expression a= 2+2;. // means a=4 But due to postfix increment operator (a++) the value of a increases by 1 as soon as control shift to next line in the program. Therefore printf (%d,a); prints 5 I hope this will clear your doubt

vishal rana
  • 33
  • 1
  • 1
  • 7
-1

In C, the precedence table specify the order of evaluation of expression and also specify the association rules. Using that rule we can evaluate the equal priority operator(R->L OR L->R) in a expression.
You specify,
a = 1;
x = a++ + ++a;
1: ++a then exp: a(2)++ + 2 = 4 assign to x
2: and then increment a , becomes a = 3

suppose, a = a++ + ++a; then
increment a
2 + 2 assign to a(4). increment a(5).

Muthuraman
  • 143
  • 2
  • 9
  • Hi thanks... but post increment has the highest priority then in the expression x=a++ + ++a;.... a++ should have been executed first right? ie x= 1 + 3 is it like that? then the exp a=a++ + ++a should be also the same thing right? – jack Nov 18 '10 at 10:43
  • x = ++a; and x = a++; give different answer to x. Here ++a do the first and add the current value of a + a then assign to x. After again increment the value of a – Muthuraman Nov 18 '10 at 11:38
  • Can you please explain me in a general way that control flows so that so it is applicable for any type of exp like this???? – jack Nov 19 '10 at 07:01
  • Please refer the C programming by Dennis Ritchie... – Muthuraman Nov 19 '10 at 09:34
  • Precedence does not specify order of evaluation. The behavior of `a++ + ++a` is *undefined*. (And adding parentheses doesn't change that.) – Keith Thompson Dec 10 '11 at 19:39
-1

Promod answer or his explanations is not correct

The correct method to remember is

Of all the pre operators -pre increment has highest priority

And of all the post increment operations -post increment has least priority

Addition has lower priority than both pre and post increment operators

Now consider the fact that Pre increment falls in the category of Right to left

And Post increment falls in the class of Left to right

Taking the two cases into consideration one can work out the code

i = 1;
i=i++ + ++i + ++i + i++;

To be not 14 but 12

Middle two expressions are evaluated to 4 then 4+4+4

"Postfix increment/decrement have high precedence, but the actual increment or decrement of the operand is delayed (to be accomplished sometime before the statement completes execution). "

This is the proof link enter link description here

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
delete me
  • 65
  • 10
  • That expression has undefined behavior. John Bode's answer explains why. Seeing the result on a particular implementation proves nothing. – Keith Thompson Dec 10 '11 at 19:37
  • @Keith Thompsan But for few simple cases you will not say that m++ is undefined ,You cannot rule out anything to be undefined by just the sight of ++. The people who made the language are better than you . They better know what undefined means and they defined ++ for a reason . It's results are undefined when concatenated with a number of other operators but just a sight of ++ and ruling an expression as undefined is ignorance – delete me Dec 10 '11 at 20:24
  • Of course `++` by itself is not undefined. Nobody ever said it was. If you know the behavior of the expression in your answer is undefined, why are you trying to demonstrate that it results in 12 rather than 14? What exactly is your point? – Keith Thompson Dec 10 '11 at 21:53
  • My point is the answer 14 is just wrong , on no no implementation will the answer be 14 . The guy did even code up that and used some "coaching class tricks" to find out 14 – delete me Dec 10 '11 at 22:26
  • You need to understand what "undefined behavior" means. There's no reason the result couldn't be 14, or 12, or 42, or a segmentation fault, or a suffusion of yellow. And your claims about operator precedence are also incorrect; all postfix operators have the same precedence, and all (prefix) unary operators have the same precedence. – Keith Thompson Dec 10 '11 at 23:09