What use is y=x++

Hi

I’m new to C.

I am troubled by y=x++;

I was reading the reference for ++, and the reference example gives:-

x = 2;
y = ++x; // x now contains 3, y contains 3
y = x++; // x contains 4, but y still contains 3

I can understand where I would use y=++x; (I am doing two things at once i.e. incrementing x and assigning it to y).

But where would you use y=x++;?

Surely if you are doing x=x+1, then y has got nothing to do with this operation, so why bother making it look like y is being assigned with y=x++;?

Thanks

Steve

The two forms of the ++increment/decrement— operation are most often used in loops when testing the value...

Do you want the variable to change before the value is tested, or after...

Frequently used in for() loop structures.

y=x++;

y contains the previous value after this statement. You can e.g. later restore x to its original value using x = y

But where would you use y=x++;?

You wouldn't, because the result for y is not strictly defined by the C/C++ language standards.

What may work on an Arduino may not work on some other system.

jremington:
You wouldn’t, because the result for y is not strictly defined by the C/C++ language standards.

What may work on an Arduino may not work on some other system.

I’m not much of a spec person. According to http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf (page 10); I’ve added the emphasis.

If a side effect on a scalar
object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, and they are not potentially concurrent (1.10), the behavior isundefined.

My understanding is that y = x++; is safe to use and x = x++; is not (it’s also sounds quote useless :wink: )

We agree then, the construction "y=x++;" is completely useless.

jremington:
We agree then, the construction “y=x++;” is completely useless.

If that would be the case, we would have discomfort to read data from successive RAM locations of ATmega using Y pointer. For example –

clr  r29
ldi  r28, $60     ; Y register holds the address $0060
ld   r15, Y+      ; r15 <----- (0060); Y now points next RAM location (0061)
ld   r16, Y        ; r16 <-----  (0061)

jremington:
You wouldn't, because the result for y is not strictly defined by the C/C++ language standards.

What may work on an Arduino may not work on some other system.

this is totally defined in the standard....

when you do y = Z, the compiler evaluates the Z expression first and stores the returned value in y

x++ is an expression that evaluates to the value of x and increments x by 1
++x is an expression that increments x by 1 and evaluates to the resulting new value

it's all legit.

1. y = x++; is the compact form of --

y = x;
x = x+1;

2. y = ++x; is the compact form of --

x = x+1;
y = x;

sterretje:
My understanding is that y = x++; is safe to use and x = x++; is not (it's also sounds quote useless :wink: )

Same here.
As an amusing side note: sketches that contained "x = x++;" have gone different ways at different times. I think the change happened in V1.6. Before the change, the compiler gave you "x++;" which was apparently what people wanted. After the change, the compiler treated it as "x = x;" and a few sketches didn't work anymore.

@GolamMostafa... You got it.
The evaluation of x happens before or after the operation.

  1. y = x++; is the compact form of :

y = x;
x = x+1;

  1. y = ++x; is the compact form of --

x = x+1;
y = x;

Before the change, the compiler gave you "x++;" which was apparently what people wanted.

In other words, if the language standards aren't clear on what the expression means, you make stuff up as you go along. What a fun idea!

Simple use case (maybe contrived):

void Aopen( byte* P, byte END, byte START ) {
    // open one space in an array from [START] to [END] 
    int src;
    int des;

    for( des = END + 1, src = END; des > END - START - 1;  des = src-- )    // math here
        P[des] = P[src];                                                    // no math here

    P[des] = 0;
}

Thank you most kindly gentlemen. I see now!

Store x in y, and then increment x; and have the option of retrieving the original value of x as it is now in y. That makes sense. I've done this a million times in Basic (if I can say that word around here :grin: ), but used y=x then x=x+1.

Steve

Well technically C++ 17 made some progress in what is defined versus Undefined behavior (see sequencing rules —> Undefined behavior)

See the doc:

Prefix versions of the operator return references and postfix versions return values
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.
Because of the side-effects involved, built-in increment and decrement operators must be used with care to avoid undefined behavior due to violations of sequencing rules.
Because a temporary copy of the object is constructed during post-increment and post-decrement, pre-increment or pre-decrement operators are usually more efficient in contexts where the returned value is not used.

As a real-world example, you want to serially shift a byte value to a digital pot which in turn will control the brightness of an LED. To fade in or out, you loop and increment the pot value but when you do the shift out you destroy the variable so you assign x++ to a temp and shift out the temp.

Hello

Before talking about the usefullness or side effects of such expressions, people should have to learn how to disassemble and understand the generated code.

Best Regards,
bidouielleelec