Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is `f().items()` wrong in the range-based for statement with initializer example [duplicate]

Tags:

c++

c++20

In his report on the Fall 2017 standards meeting, Herb Sutter has the following example of what the range-based for statement with initializer is simplifying:

{
  T thing = f();
  for (auto& x : thing.items()) {
    // Note: “for (auto& x : f().items())” is WRONG
    mutate(&x);
    log(x);
  }
}

Why is for (auto& x : f().items()) wrong? That is, when does f().items() yield undefined behavior but T thing = f(); ... thing.items() not yield it?

(This question might be considered a duplicate but the answer was only revealed by writing the question, not by normal search, so I decided it was worthwhile including in StackOverflow.)

like image 627
Eponymous Avatar asked Jul 14 '26 04:07

Eponymous


1 Answers

If t.items() returns a reference to a member of t, then f().items() will give you a dangling reference and thus undefined behavior.

Breaking it down: f() will be a temporary that will be destroyed after the items() call returns. If items() returns a reference to a member of that temporary, it will become dangling once the temporary is destroyed.

See https://stackoverflow.com/a/40955021/309334 for more detail and a way of writing your methods so they won't have this problem.

like image 89
Eponymous Avatar answered Jul 15 '26 20:07

Eponymous