1

I was watching this video (timestamp), and this code exhibits undefined behavior.

struct S {
    std::vector<int> data{1, 2, 3, 4, 5};
    const auto& get_data() const { return data; }
};

S get_s() { return S{}; }

int main() {
    for (const auto &v : get_s().get_data()) {
        std::cout << v;
    }
}

He says that the expanded version of the for is exactly this, which I understand.

    auto && __range = get_s().get_data(); // This line
    auto __begin = begin(__range);
    auto __end = end(__range);
    for (; __begin != __end; ++__begin()) {
        std::cout << v;
    }

Auto ref-ref would extend the lifetime of the thing returned by get_s, not the thing returned by get_data.

I don't think he misspoke either, as he goes on to say

[...] dangling reference to the object of type S

Why is that so? Shouldn't the RHS be completely evaluated before assignment to the LHS?

Also, not sure how to title this question, or what to exactly search for, please let me know so that I can better search for resources next time. Thanks.

B_Dex_Float
  • 142
  • 2
  • 11
  • Lifetime extension is not transitive. The `get_s()` returned S is gone at the end of the `auto && __range = get_s().get_data();` pseudo-line. – Eljay Sep 06 '20 at 18:22
  • @StoryTeller-UnslanderMonica I'm not so sure, he goes on to later say, "[...] dangling reference to the object of type S" – B_Dex_Float Sep 06 '20 at 18:25
  • @B_Dex_Float - It's not impossible to misspeak more than once when presenting. – StoryTeller - Unslander Monica Sep 06 '20 at 18:32
  • @StoryTeller-UnslanderMonica Okay, fair enough. Could you make an answer proving otherwise? I'm a real beginner, so I could really use an example saying otherwise. Thanks – B_Dex_Float Sep 06 '20 at 18:45
  • There is a way to interpret this other than as errors: you can’t lifetime-extend a return value that is already a reference (like that of `get_data`), and that reference is *into* a destroyed object of type `S`. – Davis Herring Sep 15 '20 at 12:51
  • Not sure why this is closed. The linked question doesn't answer mine, as I understand what's happening there. My specific question is to _why_ the ref-ref would extend the lifetime of the thing returned by `get_s`. – B_Dex_Float Sep 15 '20 at 18:20
  • @DavisHerring Why is the lifetime extension into the thing returned by `get_s`? Shouldn't it try to do that to the thing returned by `.get_data()`? I mean shouldn't the RHS be evaluated before 'assignment (or ref ref capture etc...)' to the LHS? What am I missing here? Because if ref-ref is binding to the thing returned by `get_s()` then ... I'd be at a loss of words, trying to understand that (since I think the RHS has to be evaluated completely before the LHS is determined)! – B_Dex_Float Sep 15 '20 at 18:23
  • I'm quite disappointed that I can't even see my question, and is instead redirected to the one marked duplicate. Thanks. – B_Dex_Float Feb 03 '21 at 19:55

0 Answers0