-3
#include <iostream>
int main(int argc, char *argv[]) {
    int x = 3;
    int y;
    int *px = &x;
    y = *px--;
    *px = 5;
    std::cout << "&x = " << &x << " px = " << px << " &px = " << &px << "&y =" << &y; // strange line
    std::cout << "x = " << x << " y = " << y << std::endl;
    std::cin.get();
}

When I use &y in "strange line", system prints out x = 3, y = 5, this can be explained, because in actual stack memory, x's address in highger place, y's address in lower place (y's address = x'address - 4), so *px = 5 change y's value;

BUT! Something very strange happens, when I use y instead of &y in "strange line", x = 3 and y = 3! What happend? It seems that even I use "g++ -O0", nothing changes, so it's not compiler's fault, so why? Picture following:

enter image description here enter image description here enter image description here enter image description here

Tumb1eweed
  • 85
  • 6
  • 6
    You're just smashing around in the stack here. This is all undefined behaviour. – tadman Sep 15 '20 at 01:50
  • Do not assume the address location `x` and `y` are related. Unless are you trying to understand how gcc implement undefined behavior. However it's not needed. – Louis Go Sep 15 '20 at 01:54
  • If you want an explanation for what is happening, you need to look at the assembly code. We evolved away from lower level coding to higher level coding to avoid weird things like this. Follow the bounds of the language and it will treat you well. – JohnFilleau Sep 15 '20 at 01:54
  • But I print out &x and &y, they are actually near... @LouisGo – Tumb1eweed Sep 15 '20 at 01:56
  • It's not defined in standard. It seems near in a small program, but don't depend on this behavior. – Louis Go Sep 15 '20 at 02:01
  • *It seems that even I use "g++ -O0", nothing changes* --- What does the optimization level have to do with where the local variables are stored in the stack? Also, you should print separate lines, no comments on each line. The code you posted is confusing with the comments in that line, and we have to figure out what you're trying to print. – PaulMcKenzie Sep 15 '20 at 02:01
  • I print out &x and &y, &x = 0x65fe1c &y = 0x65fe18 – Tumb1eweed Sep 15 '20 at 02:05
  • sorry sorry, i just too excited to delete my comments. I know it should't relate to optimization level, but I just can't find another explanation to answer it. @PaulMcKenzie – Tumb1eweed Sep 15 '20 at 02:08
  • 2
    `*px = 5 change y's value` No. That's just invoking [undefined behavior](https://en.cppreference.com/w/cpp/language/ub). Using a different compiler might crash the program, instead, or g++ could output different numbers when you compile tomorrow or the next version comes out. – dxiv Sep 15 '20 at 02:24
  • 5
    Instead of trying to guess why this behavior is happening, look at the assembly code. It will tell you why this is happening. Playing 20-guesses golf with trying to figure out undefined behavior isn't something that serious C++ users care to do. We just avoid undefined behavior. This reminds me of the joke, "Doctor, it hurts when I do this!". "Don't do that then." – JohnFilleau Sep 15 '20 at 02:28

1 Answers1

3

On this line:

y = *px--;

you are invoking undefined behavior by computing a pointer that is invalid. px points to an int, and it cannot be decremented. Even if px could be decremented, dereferencing it:

*px = 5;

would not be allowed, since it's not pointing at valid memory.

The program might do anything at all, and analyzing the output it produces is not meaningful, at least within the rules of the language.

cigien
  • 57,834
  • 11
  • 73
  • 112
  • But I print out &x and &y, &x = 0x65fe1c &y = 0x65fe18, Isn't it px point to y? – Tumb1eweed Sep 15 '20 at 03:32
  • No, not at all. There's no requirement for anything to be pointing anywhere. That's just what UB is. – cigien Sep 15 '20 at 03:34
  • But still can't explain why when I use &y it becomes x = 3 y = 5, and I dont use any reference or address about y, it becomes x = 3 y = 3, – Tumb1eweed Sep 15 '20 at 03:50