confusing C statement

Status
Not open for further replies.

sawaak

Full Member level 2
Joined
May 20, 2003
Messages
146
Helped
4
Reputation
8
Reaction score
2
Trophy points
1,298
Activity points
1,069
Hi,
here is a program.
Code:
 void main()
{
 int a = 10;
int b;

b = (a++ - --a + ++a);
printf("value of b is %d",b);

b = a + b;
printf("Now value of b is %d",b);
}

the answer i got on Turbo C compiler is
value of b is 10
Now value of b is 21.

how can it be, i m confuse

thanks
sawaak
 

Hi,
From the code, we see that we have two prefixs in incrementing a and one post fix in incrementing a. So based on this post fix will be incremented after b is assigned the value. So first value of b is 10 - 11 + 11 = 10.
Now a is incremented due to postfix. a = 11. so new value of b is 21.
Regards,
ramana
 

what it boils down to as ramana_k22 said:
example
a = 10; b = 0;
a++ + a => 10 + 10 = 20 and then a++; a =11;
++a + a => 11 + 11 since first a++, then a+a;
 

Yes, you can muddle through an explanation of the equation. But this is an example of a very serious problem in the C standard, it isn't a consistant standard. The writers of C compilers are allowed the benefit of generating code for statements in any order they choose as long as the order the code is generated in is at the same priority level.

This means that x = a + b + c can cause the compiler to create code for
x = (a+ b) + c or x = a + (b + c)

This means that the pre and post decrement code all goes to hell along with the program that uses such code. First rule of thumb when using C code - use explicit parenthises to give the compiler explicit instructions on how to generate the code, plus it makes the code a hundred times more readable to us humans. Bottom line, if you write such ambiguous code you need to learn how to make it unambiguous.

It's the same way that some people take NULL to be zero in C. It is not zero. The capitol letters should tell you it is a 'define'd constant. It is the value the writer of the C compiler chooses to be an invalid pointer. For most C compiler implementations, it is 0, but for some implementations, it may be the exception vestor or trap vector for unassigned pointer.

Lesson so far: never let your code be ambiguous, you can't use enough parenthesis to make it unambiguous. It will help your career-path immensely.

PS - You should see the crazy side effects the define statement can cause if you don't put parenthesis around absolutely everything, and I mean everything. Some of the effects are mind-boggling. It's one of the reasons why the define statement is on it's way to extinction in C++. Compilers and pre-processors really don't co-exist very well together.
 

There is no such problem in the C standard. It says an expression is not allowed to modify a variable more than once between sequence points. The statement b = (a++ - --a + ++a); violates that rule, so the results are undefined (anything could happen). To use such code in your program is a bug, even if it gives you the results you expected.

All C programmers should read the comp.lang.c FAQ. It's packed with excellent advise, including the topic we are currently discussing.
**broken link removed**

I also recommend using a more modern compiler than Turbo C. When I compile the example with MinGW, its warning messages identify several bugs, including the one we are currently discussing:
confusing.c:2: warning: return type of 'main' is not `int'
confusing.c: In function `main':
confusing.c:6: warning: operation on `a' may be undefined
confusing.c:6: warning: operation on `a' may be undefined
confusing.c:7: warning: implicit declaration of function `printf'
 
Last edited by a moderator:


**broken link removed**
I found there so much useful things, so i also found the answer of this problem there, i also suggest everyone want to write good c programe to go to there have a look.
 
Last edited by a moderator:

HI,

In this statement b=(a++ - --a + ++a);
'a' value will be incremented one time and decremented one time because of prefix increment and the value will be 10. a++ will be 10 no change in the value because of postfix increment operator and after the execution of the above statement the value of 'a' will be 11. Now in the first printf the value will be 10 and in the next printf statement the value of 'b' will be 21.
 

aandavan, it's allowable for a compiler to behave that way, but don't rely on it. The C standard says the results are undefined.
 

Hi ech047,
I checked with two compilers TurboC and Epic turbo C. I got the same answer. Thats why I thought all the compilers would produce same result. But in keil the answer is different. So I confirmed that the value may depends on the compiler
 

sawaak said:
... how can it be, i m confuse
The solution to your confusion is simple: don't write obfuscated code!

To avoid confusion, write code that is clear and easy to understand. Also, comment your code so that your intent will be clear to others (and you, too!).

I realize your confusing code is a purely an academic exercise, but it's rather pointless to explore the behavior of code that will never see the light of day in a practical application.
 

I suggest you follow the MISRA rules when writing code. This is an effort by the motor industry to write code that should work with all compilers.
 

What is MISRA? If you want to write good portable C code, follow the ISO/IEC/ANSI C Standard, not some other set of rules, and not some compiler's behavior. Of course, the standard isn't very good for learning C.

Update: I discovered that MISRA (the Motor Industry Software Reliability Association) publishes "Guidelines for the Use of the C Language in Critical Systems". That book says to use C only as defined in the ISO standard, and then adds additional requirements to help the programmer avoid common C mistakes. That sounds like a good thing!
 

U shouldn't use such kind of codes in C.. Its execution is undefined in C language . The results may varry from compiler to compiler.
 

Use parenthesis..that will make it easier and clearer for u and for those who read your code..and for the compiler!!!

In this way of writting the code..different compilers will give u different answers!!!
 

the answer is simple

First assignment... 10 -11 + 11 gives 10

Now A=11 and B=10
so,A+B=11+10=21

this again depends upon the compiler and of course, little bit difficult to debug
Don't use such a coding in program
Use paranthesis for separation
 

It is a good idea to do static analysis on your code, using something like Gimpel lint. Gimpel also supply a MISRA checking file as well. You'd be surprised how many bugs can be detected by static analysis!
In the automotive industry, software has to be MISRA compliant.
MISRA is very fussy about types!
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…