Как обеспечить разыменование происходит только один раз - PullRequest
2 голосов
/ 30 мая 2019

Есть ли способ гарантировать, что разыменование происходит только один раз, а значение из разыменования загружается из / сохраняется только один раз? Например

class X {
public:
  std::pair<int, int> p;
};

void bar(std::pair<int, int>);

void foo(X* pointer) {
  auto pr = pointer->p;
  bar(pr);
}

int main() {
  auto&& go = std::atomic<bool>{false};
  auto&& x = X{};
  auto&& thread = std::thread{[&]() {
    while (!go.load(std::memory_order_acquire)) {}
    foo(&x);
  }};

  x = create();
  go.store(true, std::memory_order_release);
  thread.join();
}

Допустимо ли, чтобы компилятор загружал из указателя более одного раза, есть ли способ гарантировать, что загрузка будет происходить только один раз? Если я добавлю volatile к foo(), я не смогу передать разыменованную пару в bar(), потому что я бы выбрасывал volatile -ness из p.


Примером того, где это может быть полезно, является наличие устройства, подключенного для приема ввода-вывода от одного из портов устройства. Тогда важно, чтобы вы читали с указателя только один раз. Поскольку каждое чтение что-то значит для устройства. Кроме того, если у вас есть другой код, который не имеет дело с энергозависимыми типами, было бы важно разыменовать указатель и передать энергонезависимый объект во внешний код.

...