Sequence point.

Discussion in 'C Programming' started by somenath, Sep 30, 2013.

  1. somenath

    somenath Guest

    I am not able to understand why the following program output as follows.

    #include<stdio.h>
    void test(int x,int y)
    {
    printf("x = %d\n",x);
    printf("y = %d\n",y);

    }


    int main(void)
    {
    int i =5;
    int j =5;
    test(++i,j++);

    return 0;
    }

    $ ./a.exe
    x = 6
    y = 5

    According to my understanding function call provide sequence point i.e all the side effect will be guaranteed to be complete ( after the evaluation of all the arguments, and just before the actual cal).
    so in case of j++ the value of the expression is j but as a side effect j gets incremented by 1. So test will receive the value 6,6.
    Where am I going wrong here ?
    somenath, Sep 30, 2013
    #1
    1. Advertising

  2. somenath

    Eric Sosman Guest

    On 9/30/2013 11:17 AM, somenath wrote:
    > I am not able to understand why the following program output as follows.
    >
    > #include<stdio.h>
    > void test(int x,int y)
    > {
    > printf("x = %d\n",x);
    > printf("y = %d\n",y);
    >
    > }
    >
    >
    > int main(void)
    > {
    > int i =5;
    > int j =5;
    > test(++i,j++);
    >
    > return 0;
    > }
    >
    > $ ./a.exe
    > x = 6
    > y = 5
    >
    > According to my understanding function call provide sequence point i.e all the side effect will be guaranteed to be complete ( after the evaluation of all the arguments, and just before the actual cal).
    > so in case of j++ the value of the expression is j but as a side effect j gets incremented by 1. So test will receive the value 6,6.
    > Where am I going wrong here ?


    The test() function prints the values x,y -- not the values i,j.
    The expression `++i' adds 1 to `i' and yields the new value; that is
    the value that `x' receives. The expression `j++' adds 1 to `j' and
    yields the original value; that original value is what `y' receives.
    At the point of the printf() calls, then, `x' is 6 and `y' is 5. As
    it happens, both `i' and `j' are now 6, but they're not what test()
    prints.

    Try this modified program; perhaps it will help you understand:

    #include <stdio.h>
    int i = 5; // formerly in main(), now at file scope
    int j = 5; // ditto

    void test(int x, int y) {
    printf("x = %d, y = %d\n", x, y);
    printf("i = %d, j = %d\n", i, j);
    }

    int main(void) {
    test(++i, j++);
    return 0;
    }

    --
    Eric Sosman
    d
    Eric Sosman, Sep 30, 2013
    #2
    1. Advertising

  3. somenath

    Guest

    On Monday, September 30, 2013 3:17:14 PM UTC, somenath wrote:
    > I am not able to understand why the following program output as follows.
    >
    >
    >
    > #include<stdio.h>
    >
    > void test(int x,int y)
    >
    > {
    >
    > printf("x = %d\n",x);
    >
    > printf("y = %d\n",y);
    >
    >
    >
    > }
    >
    >
    >
    >
    >
    > int main(void)
    >
    > {
    >
    > int i =5;
    >
    > int j =5;
    >
    > test(++i,j++);
    >
    >
    >
    > return 0;
    >
    > }
    >
    >
    >
    > $ ./a.exe
    >
    > x = 6
    >
    > y = 5
    >
    >
    >
    > According to my understanding function call provide sequence point i.e all the side effect will be guaranteed to be complete ( after the evaluation of all the arguments, and just before the actual cal).
    >
    > so in case of j++ the value of the expression is j but as a side effect jgets incremented by 1. So test will receive the value 6,6.
    >
    > Where am I going wrong here ?


    From http://en.cppreference.com/w/cpp/language/operator_incdec :

    pre-increment and pre-decrement operators increments or decrements the value of the object and returns a reference to the result.

    post-increment and post-decrement creates a copy of the object, increments or decrements the value of the object and returns the copy from before the increment or decrement.

    So when you type `j++`, the compiler interprets that as: create a copy of j, then increment the original j, and then pass in the value of the copy to the function. These are the 'side effects' you allude to, and they do indeed all complete before the function call. This is the easiest way to get as close as possible to our intuition - that j++ means 'do all the things toj, and then increment j'.

    It would also be a lot less useful if test(i, j++) and test(i, ++j) did thesame thing.
    , Sep 30, 2013
    #3
  4. somenath

    Eric Sosman Guest

    On 9/30/2013 11:28 AM, wrote:
    > [...]
    > From http://en.cppreference.com/w/cpp/language/operator_incdec :

    ^^^ ^^^

    Wrong language. C and C++ are not the same.

    > pre-increment and pre-decrement operators increments or decrements the value of the object and returns a reference to the result.


    No: Both operators yield the *value* (pre- or post-) of the object.
    Neither yields a reference; C does not have references.

    > post-increment and post-decrement creates a copy of the object, increments or decrements the value of the object and returns the copy from before the increment or decrement.


    No: Neither operator copies an object, nor does either yield
    a copied object.

    > So when you type `j++`, the compiler interprets that as: create a copy of j,


    No.

    > then increment the original j, and then pass in the value of the copy


    No.

    > It would also be a lot less useful if test(i, j++) and test(i, ++j) did the same thing.


    Here, you're right.

    --
    Eric Sosman
    d
    Eric Sosman, Sep 30, 2013
    #4
  5. somenath

    James Kuyper Guest

    On 09/30/2013 11:38 AM, Eric Sosman wrote:
    > On 9/30/2013 11:28 AM, wrote:
    >> [...]
    >> From http://en.cppreference.com/w/cpp/language/operator_incdec :

    > ^^^ ^^^
    >
    > Wrong language. C and C++ are not the same.
    >
    >> pre-increment and pre-decrement operators increments or decrements the value of the object and returns a reference to the result.

    >
    > No: Both operators yield the *value* (pre- or post-) of the object.
    > Neither yields a reference; C does not have references.


    Not to disagree with you, but simply to clarify:
    Even though C and C++ are not, in general, the same, and even though C
    does not have references, both languages handle the relevant aspects of
    ++ and -- the same.
    C++ operator overloads for those operators are typically written in the
    manner he describes, and C++ handles overload resolution using the
    concept of operator overload functions for built-in type which have the
    same type of function signature. However, those functions don't have to
    actually exist, the concept that they do is just a convenient way to
    organize overload resolution so it handles built-in types in a way
    that's consistent with the way it handles user-defined types. The
    description of how the increment and decrement operators actually work
    for built-in types is very similar to the corresponding section of the C
    standard, and makes no mention of those overloads.
    James Kuyper, Sep 30, 2013
    #5
  6. somenath

    somenath Guest

    On Monday, September 30, 2013 8:54:54 PM UTC+5:30, Eric Sosman wrote:
    > On 9/30/2013 11:17 AM, somenath wrote:
    >
    > > I am not able to understand why the following program output as follows.

    >
    > >

    >
    > > #include<stdio.h>

    >
    > > void test(int x,int y)

    >
    > > {

    >
    > > printf("x = %d\n",x);

    >
    > > printf("y = %d\n",y);

    >
    > >

    >
    > > }

    >
    > >

    >
    > >

    >
    > > int main(void)

    >
    > > {

    >
    > > int i =5;

    >
    > > int j =5;

    >
    > > test(++i,j++);

    >
    > >

    >
    > > return 0;

    >
    > > }

    >
    > >

    >
    > > $ ./a.exe

    >
    > > x = 6

    >
    > > y = 5

    >
    > >

    >
    > > According to my understanding function call provide sequence point i.e all the side effect will be guaranteed to be complete ( after the evaluation of all the arguments, and just before the actual cal).

    >
    > > so in case of j++ the value of the expression is j but as a side effect j gets incremented by 1. So test will receive the value 6,6.

    >
    > > Where am I going wrong here ?

    >
    >
    >
    > The test() function prints the values x,y -- not the values i,j.
    >
    > The expression `++i' adds 1 to `i' and yields the new value; that is
    >
    > the value that `x' receives. The expression `j++' adds 1 to `j' and
    >
    > yields the original value; that original value is what `y' receives.
    >
    > At the point of the printf() calls, then, `x' is 6 and `y' is 5. As
    >
    > it happens, both `i' and `j' are now 6, but they're not what test()
    >
    > prints.
    >
    >
    >
    > Try this modified program; perhaps it will help you understand:
    >
    >
    >
    > #include <stdio.h>
    >
    > int i = 5; // formerly in main(), now at file scope
    >
    > int j = 5; // ditto
    >
    >
    >
    > void test(int x, int y) {
    >
    > printf("x = %d, y = %d\n", x, y);
    >
    > printf("i = %d, j = %d\n", i, j);
    >
    > }
    >
    >
    >
    > int main(void) {
    >
    > test(++i, j++);
    >
    > return 0;
    >
    > }
    >
    >
    >

    Thanks for the explanation. I missed the point that the value of the argument is passed to the function.

    So the value of the expression j++ is 5 but the value of j is 6 and the value of the expression that is 5 is passed to the function.
    somenath, Sep 30, 2013
    #6
  7. On Monday, September 30, 2013 4:17:14 PM UTC+1, somenath wrote:
    > I am not able to understand why the following program output as follows.
    >
    > test(++i,j++);
    >

    The ++ operator is a bit confusing.

    In most of mathematics, precedence refers to binding as well as to order
    of application. So if we say x = 1 + 2 *3, we apply the 2*3 first, yielding
    six, then add one to it, to give 7.
    However if in C we write int i = 3; x = 1 + 2 *i++; then the ++ is applied to
    the i only, but only after everything else has been evaluated. So x is still
    7, but i is 4.
    It's a little quirk that takes a bit of getting used to, but in fact it makes
    programs easier to write.
    Malcolm McLean, Sep 30, 2013
    #7
  8. somenath

    Eric Sosman Guest

    On 9/30/2013 12:34 PM, somenath wrote:
    > On Monday, September 30, 2013 8:54:54 PM UTC+5:30, Eric Sosman wrote:
    >> On 9/30/2013 11:17 AM, somenath wrote:
    >>> [...]
    >>> int main(void)
    >>> {
    >>> int i =5;
    >>> int j =5;
    >>> test(++i,j++);
    >>> [...]

    > Thanks for the explanation. I missed the point that the value of the argument is passed to the function.
    >
    > So the value of the expression j++ is 5 but the value of j is 6 and the value of the expression that is 5 is passed to the function.


    Right. One tiny elaboration: The value of `j' *after the
    sequence point* is 6.

    --
    Eric Sosman
    d
    Eric Sosman, Sep 30, 2013
    #8
  9. somenath

    Seebs Guest

    On 2013-09-30, somenath <> wrote:
    > I am not able to understand why the following program output as follows.


    > #include<stdio.h>
    > void test(int x,int y)
    > {
    > printf("x = %d\n",x);
    > printf("y = %d\n",y);
    >
    > }


    > int main(void)
    > {
    > int i =5;
    > int j =5;
    > test(++i,j++);
    >
    > return 0;
    > }


    > $ ./a.exe
    > x = 6
    > y = 5


    Looks right to me.

    > According to my understanding function call provide sequence point i.e all the side effect will be guaranteed to be complete ( after the evaluation of all the arguments, and just before the actual cal).
    > so in case of j++ the value of the expression is j but as a side effect j gets incremented by 1. So test will receive the value 6,6.
    > Where am I going wrong here ?


    You are misunderstanding "j++". The value of the expression is not "the
    variable j", it is "the value the variable j had before this operator came
    into play".

    Imagine it as being roughly like this:

    int postinc(int *x) {
    int old = *x;
    *x = *x + 1;
    return old;
    }
    int preinc(int *x) {
    int new;
    *x = *x + 1;
    new = *x;
    return new;
    }

    The value "old" in the postinc function isn't going to change it's value just
    because you *later* modified *x.

    The entire point of postincrement is to yield the value j *used to have*. If
    sequence points changed its behavior, it would be useless.

    -s
    --
    Copyright 2013, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    Autism Speaks does not speak for me. http://autisticadvocacy.org/
    I am not speaking for my employer, although they do rent some of my opinions.
    Seebs, Oct 1, 2013
    #9
  10. somenath

    Seebs Guest

    On 2013-09-30, Malcolm McLean <> wrote:
    > On Monday, September 30, 2013 4:17:14 PM UTC+1, somenath wrote:
    >> I am not able to understand why the following program output as follows.
    >>
    >> test(++i,j++);
    >>

    > The ++ operator is a bit confusing.
    >
    > In most of mathematics, precedence refers to binding as well as to order
    > of application. So if we say x = 1 + 2 *3, we apply the 2*3 first, yielding
    > six, then add one to it, to give 7.
    > However if in C we write int i = 3; x = 1 + 2 *i++; then the ++ is applied to
    > the i only, but only after everything else has been evaluated. So x is still
    > 7, but i is 4.
    > It's a little quirk that takes a bit of getting used to, but in fact it makes
    > programs easier to write.


    I don't think it's true that it's "only after everything else has
    been evaluated". The compiler is welcome to, if it really wants,
    increment i before it does anything else in the expression, as long
    as it still uses the value 3.

    Order of evaluation and binding are logically distinct in C. If you write:
    a() + b() * c()
    the compiler is welcome to emit the three function calls in any order, as
    long as the result is computed by multiplying the results of b and c together,
    then adding that to the result of a.

    -s
    --
    Copyright 2013, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    Autism Speaks does not speak for me. http://autisticadvocacy.org/
    I am not speaking for my employer, although they do rent some of my opinions.
    Seebs, Oct 1, 2013
    #10
  11. Seebs <> writes:
    [...]
    > You are misunderstanding "j++". The value of the expression is not
    > "the variable j", it is "the value the variable j had before this
    > operator came into play".
    >
    > Imagine it as being roughly like this:
    >
    > int postinc(int *x) {
    > int old = *x;
    > *x = *x + 1;
    > return old;
    > }
    > int preinc(int *x) {
    > int new;
    > *x = *x + 1;
    > new = *x;
    > return new;
    > }
    >
    > The value "old" in the postinc function isn't going to change it's
    > value just because you *later* modified *x.
    >
    > The entire point of postincrement is to yield the value j *used to
    > have*. If sequence points changed its behavior, it would be useless.


    Right.

    The expression `j++` *could* be implemented as the equivalent of
    (j = j + 1, j - 1). The side effect of incrementing j can occur
    any time between the previous and next sequence point, as long as
    the value yielded by j++ is as specified.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Working, but not speaking, for JetHead Development, Inc.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Oct 1, 2013
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sensorflo
    Replies:
    3
    Views:
    586
    Ron Natalie
    Aug 19, 2004
  2. Dave

    Sequence point problem?

    Dave, Feb 5, 2005, in forum: C++
    Replies:
    3
    Views:
    383
    Victor Bazarov
    Feb 7, 2005
  3. sugaray

    What is sequence point ?

    sugaray, Mar 1, 2004, in forum: C Programming
    Replies:
    3
    Views:
    407
    Manish Singh
    Mar 1, 2004
  4. stef mientki
    Replies:
    13
    Views:
    618
    stef mientki
    Oct 20, 2007
  5. Saraswati lakki
    Replies:
    0
    Views:
    1,288
    Saraswati lakki
    Jan 6, 2012
Loading...

Share This Page