postfix vs prefix operator

Discussion in 'C++' started by subramanian100in@yahoo.com, India, Jun 23, 2007.

  1. , India

    , India Guest

    Consider

    int i = 10;

    Why do we say that ++i yields an Lvalue and i++ yields an Rvalue ?

    I thought both these expressions yield only values.

    I am unable to understand the difference

    Kindly explain.

    Thanks
    V.Subramanian
    , India, Jun 23, 2007
    #1
    1. Advertising

  2. wrote:
    > Consider
    >
    > int i = 10;
    >
    > Why do we say that ++i yields an Lvalue and i++ yields an Rvalue ?


    Because they do. Why do we say that water is wet?

    > I thought both these expressions yield only values.


    That would be incorrect. There are no such thing as "only values".

    > I am unable to understand the difference


    You can take an address of an lvalue, you can initialise a reference
    to-non-const with it, you can apply another increment to it...

    int i = 10;
    int *pi = &(++i);// OK
    int &ri = ++i; // OK
    ++i--; // OK

    You can't do those things with an r-value:

    int i = 10;
    int *pi = &(i++);// NOT OK
    int &ri = i++; // NOT OK
    i++--; // NOT OK

    What book are you reading that doesn't explain that?

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Jun 23, 2007
    #2
    1. Advertising

  3. , India

    Jerry Coffin Guest

    In article <>,
    says...
    > Consider
    >
    > int i = 10;
    >
    > Why do we say that ++i yields an Lvalue and i++ yields an Rvalue ?
    >
    > I thought both these expressions yield only values.
    >
    > I am unable to understand the difference


    From the looks of it, when you say "only values", you basically mean
    "rvalues".

    An rvalue is only a value -- something like zero. It doesn't necessarily
    have any storage associated with it.

    An lvalue is a variable or something along that general line -- a piece
    of storage that holds some value at any given time.

    As the difference between pre- and post-increment, the reason for the
    difference is fairly simple. In the case of pre-increment, you increment
    the variable, and the result IS that variable. In the case of post-
    increment, we increment the variable, but the result is the value the
    variable held _before_ the increment -- so the result canNOT be held in
    that variable. This means the result _has_ to be the value independent
    of the variable -- so we no longer have the address of a variable, and
    instead have only the value itself.

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
    Jerry Coffin, Jun 23, 2007
    #3
  4. , India

    , India Guest

    On Jun 24, 12:06 am, Jerry Coffin <> wrote:

    Thanks Jerry Coffin.

    Kindly clarify the following doubt also related to the Lvalue.

    Consider the following code:

    int main()
    {
    int x = 100;

    ++x = 1000;

    return 0;
    }

    If I create a C source file containing this code and compile it under
    both VC++2005 express edition and also gcc under Linux, I am getting
    compilation error for the assignment:
    ++x = 1000;
    error being invalid Lvalue in assignment.

    However if I create a C++ source file containing this code and compile
    it under VC++ 2005 and also g++, I do not get any compilation error.

    Questions:
    ----------
    1) Does it mean that prefix operator in C does not produce Lvalue in C
    unlike C++ ?

    2) I read that, in C++ postfix increment and decrement operator have
    higher precedence than the prefix operator. But in C they have the
    same precedence. Am I right or wrong ?

    Kindly explain.
    , India, Jun 24, 2007
    #4
  5. , India

    Jerry Coffin Guest

    In article <>,
    says...

    [ ... ]

    > 1) Does it mean that prefix operator in C does not produce Lvalue in C
    > unlike C++ ?


    That's correct -- in C 6.5.16/3 specifies that: " An assignment
    expression hs the value of the left operand after the assignment, but is
    not an lvalue."

    6.5.16.2/3 says: "A compound assignment of the form E1 op= E2 differs
    from the simple assignment E1 = E1 op (E2) only in thta the lvalue E1 is
    evaluated only once."

    Finally, 6.5.3.1/2 says: "The expression ++E is equivalent to (E+=1)."
    and 6.5.3.1/3 says: "The prefix -- operator is analogous to the prefix
    ++ operator, except that the value of the operand is decremented."

    So, in C a prefix increment or decrement does no produce an lvalue.

    > 2) I read that, in C++ postfix increment and decrement operator have
    > higher precedence than the prefix operator. But in C they have the
    > same precedence. Am I right or wrong ?


    You're not exactly right, but not completely wrong either. Neither the C
    nor C++ standard specifies precedence directly -- in both cases, the
    precedence must be deduced from the grammar.

    In both cases, the grammar specifies postfix operators with higher
    precedence than prefix. In reality, however, this doesn't really matter
    much -- the only time the relative precedence of a prefix and postfix
    operator matters is if both are being applied to the same operand, such
    as "++a++;".

    In C, since the operators never produce lvalues, and the operand of the
    prefix operator needs to be an lvalue, you can never have an expression
    where both the pre- and post-fix operators are applied to the same
    operand -- so there's never a conflict between the two that you need to
    resolve via precedence.

    In C++, for built-in types, the situation is the same. A user-defined
    type, however, can overload the operators and return modifiable lvalues
    in both cases:

    For example:

    #include <iostream>

    class X {
    int x;
    public:
    X(int init = 0) : x(init) {}

    int &operator++() { return ++x; }
    int &operator++(int) { return ++x; }

    operator int() { return x; }
    };

    int main() {
    X x;

    ++x++;
    std::cout << x;

    return 0;
    }

    #include <iostream>

    class X {
    int x;
    public:
    X(int init = 0) : x(init) {}

    int &operator++() { return ++x; }

    // well-formed but truly evil code:
    int &operator++(int) { return ++x; }

    operator int() { return x; }
    };

    int main() {
    X x;

    // also well-formed:
    ++x++;
    std::cout << (int) x;

    return 0;
    }

    Now, the difference in precedence is meaningful. We're applying both
    operators to the same operand, and the higher effective precedence of
    the postfix operator means the "++x++" is equivalent to:

    x.operator++(int).operator++();

    rather than:

    x.operator++().operator++(int);

    For built-in types, the postfix operators do not produce modifiable
    lvalues, so an expression like this is ill-formed, and the difference in
    precedence is a moot point, just like in C.

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
    Jerry Coffin, Jun 24, 2007
    #5
  6. , India

    Jerry Coffin Guest

    In article <>,
    says...

    [ ... ]

    > 1) Does it mean that prefix operator in C does not produce Lvalue in C
    > unlike C++ ?


    That's correct -- in C 6.5.16/3 specifies that: " An assignment
    expression hs the value of the left operand after the assignment, but is
    not an lvalue."

    6.5.16.2/3 says: "A compound assignment of the form E1 op= E2 differs
    from the simple assignment E1 = E1 op (E2) only in thta the lvalue E1 is
    evaluated only once."

    Finally, 6.5.3.1/2 says: "The expression ++E is equivalent to (E+=1)."
    and 6.5.3.1/3 says: "The prefix -- operator is analogous to the prefix
    ++ operator, except that the value of the operand is decremented."

    So, in C a prefix increment or decrement does no produce an lvalue.

    > 2) I read that, in C++ postfix increment and decrement operator have
    > higher precedence than the prefix operator. But in C they have the
    > same precedence. Am I right or wrong ?


    You're not exactly right, but not completely wrong either. Neither the C
    nor C++ standard specifies precedence directly -- in both cases, the
    precedence must be deduced from the grammar.

    In both cases, the grammar specifies postfix operators with higher
    precedence than prefix. In reality, however, this doesn't really matter
    much -- the only time the relative precedence of a prefix and postfix
    operator matters is if both are being applied to the same operand, such
    as "++a++;".

    In C, since the operators never produce lvalues, and the operand of the
    prefix operator needs to be an lvalue, you can never have an expression
    where both the pre- and post-fix operators are applied to the same
    operand -- so there's never a conflict between the two that you need to
    resolve via precedence.

    In C++, for built-in types, the situation is the same. A user-defined
    type, however, can overload the operators and return modifiable lvalues
    in both cases:

    For example:

    #include <iostream>

    class X {
    int x;
    public:
    X(int init = 0) : x(init) {}

    int &operator++() { return ++x; }
    int &operator++(int) { return ++x; }

    operator int() { return x; }
    };

    int main() {
    X x;

    ++x++;
    std::cout << x;

    return 0;
    }

    #include <iostream>

    class X {
    int x;
    public:
    X(int init = 0) : x(init) {}

    int &operator++() { return ++x; }

    // well-formed but truly evil code:
    int &operator++(int) { return ++x; }

    operator int() { return x; }
    };

    int main() {
    X x;

    // also well-formed:
    ++x++;
    std::cout << (int) x;

    return 0;
    }

    Now, the difference in precedence is meaningful. We're applying both
    operators to the same operand, and the higher effective precedence of
    the postfix operator means the "++x++" is equivalent to:

    x.operator++(int).operator++();

    rather than:

    x.operator++().operator++(int);

    For built-in types, the postfix operators do not produce modifiable
    lvalues, so an expression like this is ill-formed, and the difference in
    precedence is moot, just like in C.

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
    Jerry Coffin, Jun 24, 2007
    #6
  7. , India

    James Kanze Guest

    On Jun 24, 5:12 am, ", India"
    <> wrote:
    > On Jun 24, 12:06 am, Jerry Coffin <> wrote:


    > Kindly clarify the following doubt also related to the Lvalue.


    > Consider the following code:


    > int main()
    > {
    > int x = 100;
    > ++x = 1000;
    > return 0;
    > }


    > If I create a C source file containing this code and compile it under
    > both VC++2005 express edition and also gcc under Linux, I am getting
    > compilation error for the assignment:
    > ++x = 1000;
    > error being invalid Lvalue in assignment.


    > However if I create a C++ source file containing this code and compile
    > it under VC++ 2005 and also g++, I do not get any compilation error.


    Jerry has explained most of this, including the fact that this
    is a difference between C and C++. I would add, however, that
    in C++ the expression "++x = 1000" has undefined behavior,
    because you are modifying the variable x twice without an
    intervening sequence point.

    --
    James Kanze (Gabi Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jun 24, 2007
    #7
  8. , India

    Jon Harrop Guest

    , India wrote:
    > Consider
    >
    > int i = 10;
    >
    > Why do we say that ++i yields an Lvalue and i++ yields an Rvalue ?
    >
    > I thought both these expressions yield only values.
    >
    > I am unable to understand the difference


    There is no logical reason for these choices. Just avoid all non-trivial
    parts of the C++ language. Or avoid the whole language... :)

    --
    Dr Jon D Harrop, Flying Frog Consultancy
    The OCaml Journal
    http://www.ffconsultancy.com/products/ocaml_journal/?usenet
    Jon Harrop, Jun 26, 2007
    #8
  9. , India

    Guest

    On Jun 23, 8:22 am, "Victor Bazarov" <> wrote:
    > wrote:
    > > Consider

    >
    > > int i = 10;

    >
    > > Why do we say that ++i yields an Lvalue and i++ yields an Rvalue ?

    >
    > Because they do. Why do we say that water is wet?
    >
    > > I thought both these expressions yield only values.

    >
    > That would be incorrect. There are no such thing as "only values".
    >
    > > I am unable to understand the difference

    >
    > You can take an address of an lvalue, you can initialise a reference
    > to-non-const with it, you can apply another increment to it...
    >
    > int i = 10;
    > int *pi = &(++i);// OK
    > int &ri = ++i; // OK
    > ++i--; // OK
    >



    > You can't do those things with an r-value:
    >
    > int i = 10;
    > int *pi = &(i++);// NOT OK
    > int &ri = i++; // NOT OK
    > i++--; // NOT OK
    >
    > What book are you reading that doesn't explain that?
    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask




    dear victor

    d statement ++i--; // OK
    is not a valid one.. if u compile dis it will show "++ needs
    Lvalue....
    its because the postfix operator has high precedence than a prefix
    operator.. so i-- will be done before ++i..
    so it can be written as (++i)--;// OK ...
    , Jul 18, 2007
    #9
    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. Sergey
    Replies:
    6
    Views:
    2,909
    Victor Bazarov
    Apr 1, 2005
  2. Christian Christmann

    prefix vs. postfix

    Christian Christmann, May 14, 2005, in forum: C++
    Replies:
    2
    Views:
    5,826
    Rolf Magnus
    May 14, 2005
  3. sathya_me
    Replies:
    7
    Views:
    786
  4. shan

    diff bt postfix and prefix unary

    shan, Oct 10, 2005, in forum: C Programming
    Replies:
    2
    Views:
    350
    Chris Dollin
    Oct 10, 2005
  5. Replies:
    104
    Views:
    10,981
    Jordan Abel
    Oct 28, 2005
Loading...

Share This Page