0

I'm trying to modify a variable by a pointer, the problem is that they have the same address but the output is not right.

Here's the code:

int *ret;
int set = 56;

ret = (int *)&ret - 1;
*ret = 3;

cout << ret << endl << &set << endl << set <<endl;

The output is:

0x61ff08
0x61ff08
3

This look great, but what is really weird is that when I replace:

cout << ret << endl << &set << endl << set <<endl;

With this:

cout << ret << endl << set <<endl;

The output becomes:

0x61ff04
56

The pointer change of value and the set variable isn't modified though. It's like if I take out the &set of the cout the address pointed of the pointer exchange his address with the variable.

If I do this:

ret = (int *)&ret + 1; // instead of -1

The output becomes:

0x61ff0c
3

Can I have an explanation? I didn't find any documentation about this.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Rzdhop
  • 37
  • 9
  • 3
    The compiler isn't required to order local variables in any particular order, so your pointer arithmetic won't be consistent. – Mark Ransom Nov 05 '19 at 21:29
  • 5
    You're invoking undefined behaviour, it might happen to work sometimes but the compiler is free to not make your code do what you expect it to – Alan Birtles Nov 05 '19 at 21:29
  • 2
    You've simply discovered the different kinds of ways that C++ makes it possible [for demons to fly out of your nose](http://www.catb.org/jargon/html/N/nasal-demons.html), that's all. – Sam Varshavchik Nov 05 '19 at 21:34
  • When you removed `&set`, the compiler was then free to optimize away the `set` variable since it saw you not using `set` anywhere other than in your `cout` statement. That would explain your second output. – Remy Lebeau Nov 05 '19 at 21:34
  • ok i understood that the compiler is making he's own way to give the address to the pointers/variable, so the right way to do it is (i suppose) is ``` ret = (int *)ret - ((int)(ret - &set)) ``` (i don't want to use the basic ret = &set) – Rzdhop Nov 05 '19 at 21:56
  • 4
    The "right way" is `ret = &set;`, all the other attempts are undefined behaviour which means anything at all may happen – M.M Nov 05 '19 at 22:04

2 Answers2

0

Can I have an explanation? I didn't find any documentation about this.

Main documentation in this case is C++ standard, though it is sometimes not to easy to find and comprehend information from there. So short version in your case - you can only subtract or add integers to a pointer when resulting pointer would point to an element in the same array or pointing to the fictitious element behind the last (in this case it is illegal to dereference your pointer). For this purpose single variable is treated like one element array (so for pointer to single variable you can basically only do pointer + 1). All other hacky tries to access variables through magic with pointer arithmetics are illegal and lead to Undefined Behavior.

Details about UB you can find here What exactly do "IB" and "UB" mean?

Slava
  • 43,454
  • 1
  • 47
  • 90
-2

The answer was that the compiler is giving address by he's own way to the variable/pointers according to the code so the addresses can change, to fix this problem by only using addresses

instead of :ret = (int *)&ret - 1;

we can use :ret = (int *)ret - ((int)(ret - &set));

(i didn't want to use the basic ret = &set because i was trying to do it by manipulation only addresses)

Rzdhop
  • 37
  • 9