tl; dr doNotOptimizeAway creates an artificial "use".
A little terminology here: "def" ("definition") is an operator that assigns a value to a variable; "use" is an operator that uses the value of a variable to perform some operation.
If from the point immediately after def all the paths to the program exit are not found using a variable called def dead , and skipping Dead Code Elimination (DCE) removes it. This, in turn, can lead to other defs becoming dead (if this def was used due to the presence of variable operands), etc.
Imagine a program after Scalar Replacement of Aggregates (SRA) that turns a local std::vector into two variables, len and ptr . At some point, the program assigns a ptr value; This statement is def.
Now the source program did nothing with the vector; in other words, there was no use of either len or ptr . Therefore, all their defs are dead, and DCE can remove them, effectively deleting all the code and making the mark useless.
Adding doNotOptimizeAway(ptr) creates an artificial use that prevents DCE from removing defs. (As a note, I don't see the point in "+", "g" should be enough).
A similar line of reasoning can be accompanied by loading and storing memory: the storage (def) is dead if there is no path to the end of the program that contains the loading (use) from this storage. Since tracing arbitrary memory locations is much more complicated than tracing individual pseudo-registration variables, the compiler argues conservatively - the storage is dead if there is no way to the end of the program that may encounter the use of this storage.
One such case is a storage in the memory area, which, as guaranteed, should not be an alias - after freeing the memory, there can be no use of this storage, which does not cause undefined behavior. IOW, such applications do not exist.
Thus, the compiler can eliminate v.push_back(42) . But escape occurs - this causes v.data() be considered arbitrarily matched, like @Leon described above.
The purpose of clobber() in this example is to create an artificial use of all memory with an alias. We have a repository (from push_back(42) ), the repository is in a global alias (due to escape(v.data()) ), so clobber() can potentially contain the use of this repository (IOW, the effect of the repository is to be observed) , therefore, the compiler is not allowed to delete the repository.
A few simple examples:
Example I:
void f() { int v[1]; v[0] = 42; }
This does not generate any code.
Example II:
extern void g(); void f() { int v[1]; v[0] = 42; g(); }
This only generates a call to g() , without memory. Function g cannot access v because v not an alias.
Example III:
void clobber() { __asm__ __volatile__ ("" : : : "memory"); } void f() { int v[1]; v[0] = 42; clobber(); }
As in the previous example, no storage is generated, since v not smoothed, and the clobber call is not attached to anything.
Example IV:
template<typename T> void use(T &&t) { __asm__ __volatile__ ("" :: "g" (t)); } void f() { int v[1]; use(v); v[0] = 42; }
This time, v is escaping (i.e. it may be potentially available from other activation frames). However, the storage is still deleted, because after it there was no potential use of this memory (without UB).
Example V:
template<typename T> void use(T &&t) { __asm__ __volatile__ ("" :: "g" (t)); } extern void g(); void f() { int v[1]; use(v); v[0] = 42; g();
And finally, we get storage because v escapes, and the compiler should conservatively assume that the call to g can access the stored value.
(for experiments https://godbolt.org/g/rFviMI )