Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Why is the output like this??? 1

Status
Not open for further replies.

sreenath205

Programmer
Dec 9, 2003
17
0
0
IN
Code:
=================================
#include<stdio.h>
{
void main()
{
int i,j;
i=5;
j=++i * ++i;
printf(&quot;%d&quot;,j);
}
}
Out put:49
=================================

The output should be 42 why is it 49
Thanks in advance
 
the unary operator (++) has precedence over the arithmetic operator (*), so each ++i is evaluated first, resulting in i becoming 7 by the time multiplication is done.
 
> void main()
main returns an int

A program which runs to completion successfully would have
Code:
return 0;
as the last statement in main()

> j=++i * ++i;
Multiple side effects on the same object are ALWAYS undefined.
No amount of evaluation order, precedence or parentheses will ever fix this problem.
I suggest you study the above FAQ until you're really comfortable with what a sequence point is.

The only answer is to write a simpler expression, say
Code:
j = (i+1)*(i+1); i+=2;

--
 
> the unary operator (++) has precedence over the arithmetic operator (*), so each ++i is evaluated first
Wrong - this is not a precedence problem at all. If it were just down to precedence, then wrapping up the increment inside a function call would make no difference to the results.

This is simply not the case.

Code:
#include <stdio.h>

/* does nothing except return the passed parameter */
/* In other words, a rather expensive No Operation */
int f ( int a ) {
  return a;
}

int main ( ) {
  int i,j;
  i=5;
  j=++i * ++i;
  printf(&quot;%d\n&quot;,j);
  i=5;
  j= f(++i) * f(++i);
  printf(&quot;%d\n&quot;,j);

  i=5;
  j=i++ * i++;
  printf(&quot;%d\n&quot;,j);
  i=5;
  j= f(i++) * f(i++);
  printf(&quot;%d\n&quot;,j);

  return 0;
}
By your argument, if it were just down to precedence, then these would be the same - but they're not.
[tt]
VC7.NET Debug - 49,49,25,30
VC7.NET Release - 49,49,25,25
VC6 Debug - 49,42,25,30
VC6 Release - 49,49,25,30
gcc 3.3.1 Debug - 49,42,25,30
gcc 3.3.1 Release- 49,42,25,30
[/tt]

Any code which produces
- different answers between debug and release
- different answers between compilers
is wrong.

You can't debug such code (the release will be different), and you can't port your code to another compiler. Even updating your compiler will break your code.



--
 
You could, if you're so minded, start guessing that what your compiler has done is (1) assessed all the prefixed ++'s and done them, and Then (2) gone on to do the arithmetic. OK, in a sense you could call this &quot;taking precedence&quot;, but it isn't really, not in the same sense as parentheses(()) in an expression. What goes on in one set of parentheses, late in an expression, can't affect the value of what was evaluated earlier in the expression, but that is what is happening here. The second ++i affects the first one's value at the time of calculation.

BUT, although it's worth understanding the way your compiler thinks, Salem is utterly right, you simply cannot assume other compilers think the same way, unless it's clearly written in the language's definition.

I personally have a horrible aversion to statements like this; they may save two or three characters and get a teeny bit more done in a single line of code, but what's wrong with calculating what you need to know and then changing the variables separately? It's much more readable than a 2-things-at-once line (in my peronal view).

The other ones to beware of are changes to values in boolean expressions that may or may not get evaluated depending on whether the compiler is optimising (i.e. it's worked out that the overal AND is bound to be false, so it stops evaluating the rest). Oh, and what about functions returning boolean values but meanwhile altering global variables....


 
screenath205's snippet is an exemplary C Standard violation example. Remember that operation ++ has a side effect (memory content increment). Side effect of operations in the same expression is undefined by Standard (see any serious C book, expr evaluation part)...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top