increment in C++

#include<iostream.h>

void main(){
 int a=5;
 cout<<++a<<a;
 cout<<"\n";
 cout<<a;
 cout<<"\n";
}

the above code generates the following output:
65
6
but as per me the output should be as follows:
66
6
why does the incement doen't show up the second time



Answer this question

increment in C++

  • IanTedridge

    The C++ Standard (like the C Standard) defines sequence-points: these are points in the evaluation of your program when it is guaranteed that any side-effects from previous evaluations are complete.

    One sequence-point is at the end of a full-expression. So if you have an expression of the form

    int i = 0;
    int j = ++i + i;


    This statement in the Standards means that you cannot guarantee that the result of the pre-increment of i has actually been written to the memory location for i before the end of the expression: particularly it is not guaranteed to have happened before i is read as the right-hand operand to the + operator.

    To be more specific:

    int j = ++i + i;

    is not equivalent to:

    int k = ++i;
    int j = k + i;


    Which on first glance most C and C++ developers would assume it should be.

    The reason for this "relaxed" definition of the order of evaluation of sub-expressions is to allow optimizers to work to their full potential: even if some of the results can appear "strange".

    This is why I said in my previous message that you should not read and write to the same variable multiple times in the same expression.

    Multiple reads are well defined.
    One write is well defined.
    Anything else is implementation defined.


  • ErinActuateDeveloper

    It is undefined by the C++ standard.

    http://www.research.att.com/~bs/bs_faq2.html#evaluation-order

    Does VC++ 2005 give warnings about this  Maybe with /preFAST

     



  • SR99

    thanks for the reply specially the last three sentences/rules.

    int i = 0;
    int j = ++i + i;
    gives output 2.

    int k = ++i;
    int j = k+i;
    gives also 2.

    and also chk this one
    int ch=0;
    cout<<++ch+ch<<ch;
    cout<<ch;
    gives output as 
    20
    1
    why
    after the + operator i retains its incremented value but i guess as u told the value of is written to the memory location after the execution of the expression isn't it
    i guess the result should have been as
    10
    1


     


  • N. Soltic

    I think that the simple answer is complexity. This is really a language level diagnostic but the tool that would best be able to diagnose this issue would be the optimizer (you can imagine a case in which inlining a function causes mutiple reads/writes) but the optimizer doesn't usually deal with language level diagnostics.

    But we'll definitely take a look at this issue again and see if we can add such a warning.

  • Wolf-Michael Haberichter

    Unfortunately Visual C++ 2005 does not give a warning for this even with the /analyze switch (the /prefast switch has renamed to /analyze).

  • Georges Vidal

    There is a toll called lint that gives warning about this. Look a gimple software.

  • ctlok83

    pls explain the point in more detail.....
  • Max Khlupnov

    All the C and C++ Standards guarantee is that all side-effects (which includes updating memory) happen before the end of the full expression: they say nothing about when exactly these operations happen or in what order they happen. This is why depending on this type of behavior is dangerous: you just can't know in which order these operations will occur. In many cases code that works in debug mode will fail when optimizations are applied - as in this case the optimizer can re-order memory writes.

  • Juraj Borza

     Jonathan Caves MSFT wrote:
    Unfortunately Visual C++ 2005 does not give a warning for this even with the /analyze switch (the /prefast switch has renamed to /analyze).

    Is there any particular reason why this is I've noticed that most other compilers I've used don't generate warnings either. It seems like something that would be easy to detect and would also catch a lot of problems by those new to the language, and even those fairly experienced.

  • Rajpreet Singh

    In C++ the order of evaluation of sub-expressions like in your code above is implementation defined. In general you should not read and write to the same variable multiple times in the same expression.






  • Torsten Grabs

    Also, for completeness, the resultant C++ program actually has undefined behavior by the standard. This means that not only could the results vary from compiler to compiler, but the behavior doesn't even have to be documented (as opposed to the standard's definition of implementation-defined behavior, which implementations shall document).

    As well, not only is the order of operations unspecified, but the overall behavior of the full expression is undefined, meaning that you may not get any results at all; the program could prematurely terminate at that point in execution or perform any number of limitless possibilities. You generally can't predict what would happen, especially not in a portable manner, and therefore should not perform such operations. Even if tests on your compiler produce seemingly consistent results, you should avoid any undefined behavior at all costs.

    To be sure that you do not make this particular mistake in the future, only modify each object only once prior to the next sequence point of an expression. Sequence points in C++ are:
    1. At the end of a full expression
    2. After the evaluation of all function arguments in a function call, prior to the function body
    3. After the copying of a returned value during a function call, before execution of expressions outside of the function
    4. After the evaluation of the first operand of any of the following operators when using their built-in meaning:
      • &&
      • ||
      • :
      • ,
    One thing which is interesting to note is that because of this, when using fundamental types, expressions such as ++++i produce undefined results, whereas when using types such as class type iterators which have overloaded pre-increment operators, you get fully-defined results, since both the entrance and the exit of the operator function call are sequence points.

  • increment in C++