LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-21-2005, 07:07 PM   #1
rovitotv
Member
 
Registered: Jan 2003
Location: Dayton, Ohio
Distribution: Slackware 10.2
Posts: 116

Rep: Reputation: 15
Simple Operator Precedence C++ Problem


I am hoping somebody can explain why I am getting 8 as the answer in r instead of 6.


Program
int a = 2;
int b = 4;
int c = 6;
int r = 0;
//Increment-decrement in original location
cout << "a = " << a << " b = " << b << " c = " << c << " r = " << r << endl;
r = a * b + (--b) / (c--);
cout << "r = a * b + (--b) / (c--)" << endl;
cout << "a = " << a << " b = " << b << " c = " << c << " r = " << r << endl<< endl;


Output (from g++ 3.3.4)
a = 2 b = 4 c = 6 r = 0
r = a * b + (--b) / (c--)
a = 2 b = 3 c = 5 r = 8

Since the (--b) are in "( )" you would think b would be = to 3 so the final answer in r should be
6. Thanks.


TVR
 
Old 03-21-2005, 07:15 PM   #2
jtshaw
Senior Member
 
Registered: Nov 2000
Location: Seattle, WA USA
Distribution: Ubuntu @ Home, RHEL @ Work
Posts: 3,892
Blog Entries: 1

Rep: Reputation: 67
--b is pre-incrementation and c-- is post incrementation.

The --b is done before any of the other math is done. The c-- is done after any of the other math is done.
So you start with a = 2, b = 4, c = 6, r = 0;
b gets changed to 3 (--b). So then you get r = (2*3) + (3/6) = 8. Then c gets changed to 5.
 
Old 03-21-2005, 07:32 PM   #3
rovitotv
Member
 
Registered: Jan 2003
Location: Dayton, Ohio
Distribution: Slackware 10.2
Posts: 116

Original Poster
Rep: Reputation: 15
jtshaw,
I agree with the first part of your analysis. However I think the second part is wrong; both b and c are ints so (3/6) = 0 because the ints get truncated, so why does (2*3) + 0 = 8 it does not! The only explanation I can think of is the computer is executing (2*4) + 0 = 8. But as you say -b is pre-decrement and is in "( )" so it should run first. This seems like such a simple problem but something is screwy. Thanks for the help!
 
Old 03-21-2005, 07:34 PM   #4
Hosiah
Member
 
Registered: Sep 2004
Location: Des Moines, Iowa
Distribution: Slackware, Mandriva, Debian derivatives, +BSD/ Solaris/ Minix/ plan9/ GNU/HURD...
Posts: 185

Rep: Reputation: 31
you forgot a set of parenthesis:

r = a * (b + (--b) / (c--));

I gather that this is a simple exercise with no purpose in the real world? Because I cannot explain for certain exactly *why* C's gothic order-of-precedence rules work their black magic for every instance. In the real world for actual applications, you simply put parenthesis around every step of an operation, so that your results will always be predictable!
 
Old 03-21-2005, 07:48 PM   #5
rovitotv
Member
 
Registered: Jan 2003
Location: Dayton, Ohio
Distribution: Slackware 10.2
Posts: 116

Original Poster
Rep: Reputation: 15
Quote:
Originally posted by Hosiah
you forgot a set of parenthesis:

r = a * (b + (--b) / (c--));

I gather that this is a simple exercise with no purpose in the real world? Because I cannot explain for certain exactly *why* C's gothic order-of-precedence rules work their black magic for every instance. In the real world for actual applications, you simply put parenthesis around every step of an operation, so that your results will always be predictable!
Ok this works and while this is a simple exercise I want to know why, when the precedence table that I got out of my C++ book clearly states "( )" come before "*". Hosiah maybe operator precedence is
black magic but it should not be? Just for fun I get the same result for gcc and Visual Studio C++ version 6.


Thanks for the help
 
Old 03-21-2005, 08:35 PM   #6
jtshaw
Senior Member
 
Registered: Nov 2000
Location: Seattle, WA USA
Distribution: Ubuntu @ Home, RHEL @ Work
Posts: 3,892
Blog Entries: 1

Rep: Reputation: 67
Your right... I was thinking 6/3... opps:-P
 
Old 03-21-2005, 08:53 PM   #7
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 374Reputation: 374Reputation: 374Reputation: 374
I'll hazard a guess (I'm not at a computer I can test this on... so it might be way off).

The decrement operator evaluates as you expect, but only for that instance of b. What I mean by that is, the value substituted for "( --b )" in your expression is 4 - 1 = 3. The assignment of b's new value does not come until after processing of the line is complete. If that is the case, your first reference to b substitutes the unaltered value of b. In other words:
Code:
 r = a * b + (--b) / (c--);
   = 2 * 4 + ( 3 ) / ( 6 );
   = 8 + 0;
   = 8;
The values for the variables should then be:
a = 2
b = 3
c = 5

EDIT A quick check against this could be made by using the distributive property of mathematics. change your expression to this:
Code:
 r = (--b) * ( a + 1 / (c--) );
I would bet that will give you r = 6.

Last edited by Dark_Helmet; 03-21-2005 at 08:56 PM.
 
Old 03-21-2005, 09:23 PM   #8
Hosiah
Member
 
Registered: Sep 2004
Location: Des Moines, Iowa
Distribution: Slackware, Mandriva, Debian derivatives, +BSD/ Solaris/ Minix/ plan9/ GNU/HURD...
Posts: 185

Rep: Reputation: 31
Quote:
Hosiah maybe operator precedence is
black magic but it should not be?
oops, sorry if I sounded critical! Yes, by all means, knowledge for the sake of knowledge is a valuable goal!

I guess my attitude reflects my needs. I've programmed in C, C++, BASIC, Lisp, Perl, Awk, and assembler (note: I do NOT claim to have mastered all of the above!), and have found order of operator precedence to have different rules jumping between different languages, platforms, etc. I get my brain boggled trying to remember which punctuation character means modulus in which language, let alone whether "boolean and" comes before "left shift" and etc! So I just parenthesize on those rare occasions when I actually need to do multiple calculations in a single statement (usually in complex conditionals).

Happy hunting!

Incidentally, if you enjoy puzzling out perplexing problems in C, try googling "Duff's device", and the "obfuscated C contest". That will have you up all night!
 
Old 03-21-2005, 09:52 PM   #9
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 374Reputation: 374Reputation: 374Reputation: 374
I managed to find a computer I could play with and test some things. It appears that your expression falls into the "grey area" of compiler-dependent evaluation. I don't believe there are any rules for evaluation order when the same variable is referenced twice in a single expression, with one reference having a pre-decrement operator.

To illustrate this, try this code:
Code:
#include <stdio.h>

int main( int argc, char *argv[] )
{
  int a, b, c, r;

  a = 2;
  b = 4;
  c = 6;

  r = a * b + (--b) / (c--);  // Your original version
  printf( "r = %d\n", r );
  printf( "a = %d     b = %d     c = %d\n", a, b, c );

  a = 2;
  b = 4;
  c = 6;

  r = a * (--b) + b / (c--); // What should be an "equivalent" version
  printf( "r = %d\n", r );
  printf( "a = %d     b = %d     c = %d\n", a, b, c );

  return 0;
}
My version of gcc produced this output:
Code:
r = 8
a = 2     b = 3     c = 5
r = 6
a = 2     b = 3     c = 5
The moral of this story: Don't reference a variable you plan to pre-increment/decrement more than once in your expression. The compiler can choose to evaluate them in any order it likes.
 
Old 03-21-2005, 10:02 PM   #10
rovitotv
Member
 
Registered: Jan 2003
Location: Dayton, Ohio
Distribution: Slackware 10.2
Posts: 116

Original Poster
Rep: Reputation: 15
Dark_Helmet thanks for the help this really clears things up for me.

TVR
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
operator precedence in C Majjj Programming 2 07-07-2004 11:48 AM
Operator Overloading problem ashwinipahuja Programming 1 06-23-2004 05:59 AM
logical operator problem. Xiangbuilder Programming 5 09-07-2003 10:02 PM
Script file problem (or operator problem) HELP! lostone Linux - General 1 05-17-2001 06:11 PM
Script file problem (or operator problem) HELP! lostone Linux - Newbie 0 05-15-2001 07:59 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:19 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration