Is the value of this
pointer guaranteed to be constant during a lifetime of a particular object? I can't imagine a case where it would change, but don't know whether I am not missing something.

- 22,196
- 3
- 50
- 93
-
4The value of `this` pointer *always* is the value of the address of the object on which the function was called on. So the question is equivalent with *'can an object change its memory address over life time?'* – Aconcagua Jan 15 '20 at 10:20
-
2Worth noting: if one talks about lifespan informally, an object which is moved via `std::move` would change `this` pointers. Formally we would say those are two different objects, but informally one may think of them as "the same," which could breed confusion if one is not paying attention. – Cort Ammon Jan 15 '20 at 20:08
3 Answers
Is the value of
this
pointer guaranteed to be constant during a lifetime of a particular object?
Yes.
As user Aconcagua puts it: the value of this
pointer always is the value of the address of the object on which the function was called on1. So the question is equivalent with:
Can an object change its memory address over life time?
This is not possible, by definition of lifetime
2. The lifetime of an object begins when or after its storage is obtained and ends before of when it is released.
In the body of a non-static (
[class.mfct]
) member function, the keywordthis
is a prvalue whose value is a pointer to the object for which the function is called.
2) [basic.life]/1
(emphasis mine)
The lifetime of an object or reference is a runtime property of the object or reference. A variable is said to have vacuous initialization if it is default-initialized and, if it is of class type or a (possibly multi-dimensional) array thereof, that class type has a trivial default constructor. The lifetime of an object of type
T
begins when:
- storage with the proper alignment and size for type
T
is obtained, and- its initialization (if any) is complete (including vacuous initialization) (
[dcl.init]
), except that if the object is a union member or subobject thereof, its lifetime only begins if that union member is the initialized member in the union ([dcl.init.aggr]
,[class.base.init]
), or as described in[class.union]
.The lifetime of an object
o
of typeT
ends when:
- if
T
is a non-class type, the object is destroyed, or- if
T
is a class type, the destructor call starts, or- the storage which the object occupies is released, or is reused by an object that is not nested within
o
([intro.object]
).
-
Does this mean that it would be impossible (illegal) for a sufficiently complex runtime to implement automated memory compaction for a C++ program? Or does it just mean that it would need to behave "as-if", so as to provide the same value of `this` every time, regardless of movements in the heap? – Alexander Jan 15 '20 at 19:02
-
Hmmm, I'm not even sure how that could be made to work. Each object would need to keep an "identity" that's used as `this`, and dereferencing operations would need to use the "identity" through a lookup table maintaining by the runtime to access the real objects – Alexander Jan 15 '20 at 19:05
-
@Alexander-ReinstateMonica is a pointer *guaranteed* to be the address of an object, or is the compiler free to add a level of indirection? The lookup table idea seems workable. – Mark Ransom Jan 15 '20 at 20:23
-
@MarkRansom I don't know, but it would *at least* need to be de-reference-able. The lookup table is a total non-starter tho, it'll absolutely wreck performance. – Alexander Jan 15 '20 at 20:34
-
1@Alexander-ReinstateMonica the vtable is a similar concept that reduces performance, but it's accepted since the benefits outweigh the downside. Modern processors are really efficient with indirection. – Mark Ransom Jan 15 '20 at 20:41
-
@MarkRansom Heap compaction already has significant performance and complexity downsides, requiring it to indirect everything only makes it way worse. If the whole point of it is performance improvement, and it doesn't improve performance, there's not much a point, eh? :P And besides, vtables are relatively rare in C++, where calls are non-virtual by default, and virtual functions are de-virtualizeed by the optimizer where possible – Alexander Jan 15 '20 at 20:47
-
@Alexander-ReinstateMonica Changing ptr isn't doable. Not even on elaborate systems. Not in a low level langage (C/C++). Except maybe in very special cases. – curiousguy Jan 15 '20 at 21:22
-
@MarkRansom A vtable is a struct not an array. It doesn't have ptr arithmetic, etc. It doesn't have sub-members (members of members). Ptrs in C/C++ can point in the middle of objects which makes all GC (inexact and non compacting) more complicated. (There are ptr-to-members but they support only access not arithmetic.) Vtables aren't needed to access members except in morally virtual bases. – curiousguy Jan 15 '20 at 21:34
-
1@MarkRansom "_is a pointer guaranteed to be the address of an object, or is the compiler free to add a level of indirection?_" *By definition* that ptr is the address of an object, but "address" could be an high level abstract concept. But then if you introduce indirection, you need atomicity, you need locking, you need a bunch of additional work on all accesses of any object, if there are threads. Simply by the look and feel of it I can it's unworkable (and I haven't even considered the fact C/C++ doubles as a low level language). – curiousguy Jan 15 '20 at 21:38
-
To even have a lookup table, you would need to turn ptrs into base_addr+offset, and then turn base_addr into a ref into a table index. Then ptr arithmetic could work on offset and not base_addr. So at least that is workable but would make ptr access much more complex, even before we started making sure GC is safe. It's totally unlike Java or SML where you get these properties for free (but then you have a lot more dyn alloc w/ these runtime models for the same number of high level "objects"). – curiousguy Jan 15 '20 at 21:43
-
1@curiousguy you make good points, and I'm no longer arguing that indirection would be practical. It still makes a good thought experiment though. – Mark Ransom Jan 15 '20 at 21:47
-
Even we can restructure our house, we are not allowed to change the address. – Diamond Jan 21 '20 at 22:38
An object has a region of storage. this
points there.
An object occupies a region of storage in its period of construction (
[class.cdtor]
), throughout its lifetime, and in its period of destruction ([class.cdtor]
).
The value of this
is guaranteed to be constant if the program ever reads it, if subsequently some bits of the read value are impossible to garbage collect or if subsequently some bits of the read value escaped outside of the program. In all other cases, it behaves like a Schrödinger's cat, that is, it is constant and variable at the same time.

- 370
- 8
- 11
-
Sorry, don't understand at all. What is _to garbage collect_ and _to escape outside of the program_? – Daniel Langr Jan 23 '20 at 13:41
-
-
This does not answer my question. What is to garbage collect some bits? Or to escape them outside of the program? – Daniel Langr Jan 23 '20 at 18:34
-