Zeroing memory without optimization

Viewed 119

As you know, we cannot use memset() for zeroing a memory if it is not accessed later because it may be optimized by compiler. I saw a suggestion in cpp ref that we can use std::fill with a volatile pointer to solve this problem. Now here are my questions:

  1. Does this statement means if the pointer is not volatile, std::fill may be optimized too?
  2. How we can get a volatile pointer to a container, for example vector? Does something like this work?
vector<int> v;
volatile auto ptr = v.data();
1 Answers

Yes, this will work:

volatile int* ptr = vec.data();
std::fill(ptr, ptr+vec.size(), 0);

The one thing that prevents the compiler from optimizating it away is the volatile keyword (this is basically the whole purpose of that keyword), so std::fill with a non-volatile pointer will also be optimized.

Since memset is defined to take a non-volatile pointer, it can be optimized away even if you pass a volatile pointer to it (in which case you will also need the -fpermissive flag to allow the compiler to convert the volatile pointer to a non-volatile pointer - otherwise it will not compile).

I made a small example of the possibilities, which makes it quite visible: https://godbolt.org/z/xqYG1Ksod
(Note that I used a raw array instead of a vector, as the vector constructor would otherwise add more unrelated noise to the asm output).

Related