0

Currently I'm learning about pointers. I don't really understand what is happening the following line:

*p += a++ + (*p)++;

*p is a pointer to a. Before this line a equals 2. I expected actually that the final value would be 12. So first a will be incremented by 1. This will make a = 3, but also *p=3. When (*p)++ it will be incremented to 4 and also a will be 4. So the sum will be 4 += 4+4 --> 12.

This turns out to be wrong. So my question is: In which order are the operations happening? What is happening in the registers of the program? That explains this?

Nadine

#include <iostream>
#include <string>

int main()
{
    int a = 1;
    std::cout << "intitialisation a:"<< a << std::endl;
    int b = 2;
    int c = 3;
    {
        auto b = ++a + c++;
        std::cout << "increment a in function:" << a << std::endl;
        auto e = b;
        c += ++b;
    }
    int* p = &a;
    std::cout <<"value pointer:" << *p << std::endl;
    int* q = &b;
    ++(*q);
    std::cout << "value a before ++"<< a << std::endl;
    std::cout << "value pointer before  ++: " << *p << std::endl;
    *p += a++ + (*p)++;
    std::cout << "value a after ++"<< a << std::endl;
    std::cout << "value pointer after  ++: " << *p << std::endl;
    
    
}

output:

intitialisation a:1
increment a in function:2
value pointer:2
value a before ++2
value pointer before  ++: 2
value a after ++9
value pointer after  ++: 9
Nadine
  • 51
  • 6
  • 2
    `*p += a++ + (*p)++;` means the same as `a += a++ + a++;`. (`*p` is not a pointer to `a`, but `p` is.) – molbdnilo Nov 18 '20 at 14:04
  • @molbdnilo It doesn't "mean" _anything_. – Asteroids With Wings Nov 18 '20 at 14:04
  • 1
    fwiw, an older version of the tag description had "What not to ask: i++ + ++i and similar questions". Imho it was good that it was removed, but still there was a reason why it was in the tag descrpition. There are many similar questions about this same issue – 463035818_is_not_an_ai Nov 18 '20 at 14:09
  • @AsteroidsWithWings Of course it means *something* - that the code is making unsequenced modifications to the same object. If it didn't mean *anything*, it would be nonsense to call its behaviour undefined. – molbdnilo Nov 18 '20 at 14:25
  • @molbdnilo Undefined behaviour _literally_ means the code doesn't mean anything. There are no semantics. There is no behaviour that has been defined... A program with undefined behaviour has no meaning; that's what undefined behaviour _is_. – Asteroids With Wings Nov 18 '20 at 14:38

2 Answers2

3

The statement

*p += a++ + (*p)++;

is equivalent to

a += a++ + a++;

because p points to a. I've rewritten it since it's now explicit that the behaviour of the statements is undefined (you have reads and writes to a in unsequenced steps).

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
-2

Forget registers and order of operations. Focus on the semantics of the program.

In this case, there aren't any, because such a convoluted statement with multiple interleaved accesses has undefined behaviour.

Don't write code like this.

Asteroids With Wings
  • 17,071
  • 2
  • 21
  • 35
  • 1
    I don't follow. Demonstrating how the syntax rules of the language work *is* the semantics of the program. The OP has not indicated that they would write code like this otherwise. Also, "*convoluted statement with multiple interleaved accesses"* doesn't necessarily imply UB. At least explain where the UB comes from in the OP's code. – cigien Nov 18 '20 at 14:03
  • @cigien [Happy reading](https://stackoverflow.com/q/4176328/4386278) – Asteroids With Wings Nov 18 '20 at 14:03
  • 2
    _"Demonstrating how the syntax rules of the language work is the semantics of the program"_ It literally isn't. Syntax and semantics are two different things. – Asteroids With Wings Nov 18 '20 at 14:04
  • 1
    Thanks for the link. If you think that that post sufficiently addresses the question, then you should vote to close as a duplicate. It seems that the only thing your answer provides is advice. – cigien Nov 18 '20 at 14:05
  • @cigien And, if I did indeed think that, then I would. Thanks for your input. – Asteroids With Wings Nov 18 '20 at 14:05
  • I didn't wrote the code. It's part of a c++ course – Nadine Nov 18 '20 at 14:12
  • 1
    @Nadine: It's your job to, in a tactful way, point out to the author of the course that the statement is meaningless since its behaviour is undefined. – Bathsheba Nov 18 '20 at 14:14
  • Note that my comment emphasised *is* which is lost in your response. Yes, they are different things. In the OP's code, the purpose of the program, why it exists, its meaning if you will, is to demonstrate syntax rules. – cigien Nov 18 '20 at 14:14
  • @cigien I did you a favour by de-emphasising a falsehood ;) – Asteroids With Wings Nov 18 '20 at 14:21
  • @Persixty Yes, syntax and semantics, in concert, describe the language. This is no big secret or surprise. Doesn't mean they're the same thing. Indeed, people routinely conflate operator precedence (syntax) with order of evaluation (semantics), _particularly_ when attempting for some reason to write crazy code such as that found in this question. ‍♂️ tl;dr: I don't need your "help", thanks :) – Asteroids With Wings Nov 18 '20 at 17:06
  • @AsteroidsWithWings I know you don't need my help. I didn't intend to patronise. I thought it useful as the standard (in its wordy way) saying syntax isn't semantics. The classic is ++x doesn't increment x and take its value. It's value is `x+1` and the value `x+1` is assigned to `x`. People struggle to get their head round those aren't the same thing. – Persixty Nov 18 '20 at 17:19
  • 1
    @Persixty Ah, sorry. You literally meant "what you say". I thought you were kinda saying "what did you say?! what are you saying?!" :) – Asteroids With Wings Nov 18 '20 at 17:30