mardi 24 juillet 2018

C++ lambda by-value capture semantics and allowed optimizations

What is the compiler allowed to omit from by-value default captures, when only some data members of an implicitly captured object are actually used by the functor? E.g.,

struct A {
  // some members we care about:
  char x;
  int y;
  // some huge amount of state we do not:
  std::array<bool, 200000> z;

  int foo() const { return y + 1 }
};

void bar() {
  A a;
  // must the entirety of a be copy captured, or is the compiler allowed to pick/prune?
  auto l1 = [=](){ std::cout << a.x << ", " << a.y << std::endl; };
  // ...
}

Similarly, when if ever is early evaluation allowed to omit broader captures?

void baz(int i) {
  A a2;
  a2.y = i;

  // capture fundamentally only needs 1 int, not all of an A instance.
  auto l2 = [=](){ std::cout << a.foo() << std::endl; }
}

There are at least some situations where making a partial vs. complete copy capture of an element should have no visible external effects beyond lambda size, but I do not know where in the spec to look for the answer to what optimizations are allowable.

Aucun commentaire:

Enregistrer un commentaire