You are here:

C++/increment/decrement

Advertisement


Question
sir,
if x=3
x-=--x-x--
how answer is 1 plz tel me steps
and if i m writing like x=x---x-x--
it is coming -5
plz tel the steps in both cases

Answer
You are modifying x in both cases more than once in an expression. This is _not_ allowed and is illegal in C++ and therefore anything can happen!

Under the rules for expressions (section 5, paragraph 4 of the ISO C++ standard):

   "Except where noted, the order of evaluation of operands of
    individual operators and subexpressions of individual
    expressions, and the order in which side effects take place,
    is unspecified. Between the previous and next sequence
    point a scalar object shall have its stored value modified at
    most once by the evaluation of an expression. Furthermore,
    the prior value shall be accessed only to determine the value
    to be stored. The requirements of this paragraph shall be met
    for each allowable ordering of the subexpressions of a full
    expression; otherwise the behavior is undefined.

    [Example:
       i = v[i++]; // the behavior is unspecified
       i = 7, i++, i++; // i becomes 9
       i = ++i + 1; // the behavior is unspecified
       i = i + 1; // the value of i is incremented
    -end example]"

In particular notice the final words "otherwise the behavior is undefined" along with "a scalar object shall have its stored value modified at most once by the evaluation of an expression". I would also be suspicious of "the prior value shall be accessed only to determine the value to be stored". Your expressions are more extreme versions of the form of the third example given in the standard (i = ++i + 1;).

The reference to sequence points is a technicality as some operators, such as the comma operator, although still used in a single expression introduce a point at which previous calculations should have been done - and so the restrictions of this clause do not apply across such operators (as in the second example) - hence they invented the term sequence point.

The standard introduces side effects and sequence points thus (section 1.9, paragraph 7):

   "Accessing an object designated by a volatile lvalue,
    modifying an object, calling a library I/O function, or
    calling a function that does any of those operations are
    all side effects, which are changes in the state of the
    execution environment. Evaluation of an expression might
    produce side effects. At certain specified points in the
    execution sequence called sequence points, all side effects
    of previous evaluations shall be complete and no side effects
    of subsequent evaluations shall have taken place."

There are sequence points:

- At the completion of evaluation of a full expression
- When calling a function, after evaluation of function arguments
- After copying a function return value before execution of expressions outside the function
- When evaluating each of the following expressions there is a sequence point after evaluation of the fist expression (called a in each expression below).

   a && b
   a || b
   a ? b : c
   a , b

In this case your expressions falls only into the first case where there is a sequence point at the end of the full expression. Thus as they modify x several times, and several being more than once the expression falls into the area of undefined behaviour - which in fact means anything could happen. For example your program gives inconsistent results (either with versions built using other compilers or compiler switches, or with itself across executions), your program crashes, or even the program causes your hard disk to be reformatted. The first is most likely - that you get results that are inconsistent between compilers or compiling using the same compiler with different switches.

I think in this particular case the code could be behaving as follows:

   int x = 3;

   --x;          // x = 2
   int tmp = x - x; // tmp = 0
   x--;          // x = 1
   x -= tmp;        // x -= 0, thus x = 1

or maybe:

   int x = 3;

   --x;          // x = 2
   int tmp = x - x; // tmp = 0
   x -= tmp;        // x -= 0, thus x = 2
   x--;          // x = 1

I am presuming that your second expression statement also starts with x = 3. If so, noting this time that you are using post-increment twice then the sequence for the second expression would be behaving something like:

int x = 3;

int tmp1 = x - x;     // tmp1 = 0
int tmp2 = tmp1 - x;  // tmp2 = -3
x = tmp2;          // x = -3
x--;          // x = -4
x--;          // x = -5

Of course these are probably not the only ways to break down your expressions and obtain the results you are seeing.

In short do _not_ do what you are doing - it is illegal C++.

In general do not make expressions too complex - they are harder to get right and harder to debug (you cannot see the intermediate temporary results - and yes the compiler will use temporary objects if necessary). And sometimes compilers can get confused with certain forms of complex expressions!  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

Experience

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.

Education/Credentials

©2016 About.com. All rights reserved.