Live data from Hacker News

C++ value category cheat-sheet [pdf]

github.com

21–30 of 41 posts

Re: C++ value category cheat-sheet [pdf]

#22
post #18

Earlier quoted context omitted.

That's what I had always thought would happen; it makes sense. However, if I'm reading things correctly, the posted article disagrees, and this link also disagrees: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p013... "It is implementation-defined whether the lifetime of a parameter ends when the function in which it is defined returns or at the end of the enclosing full-expression." Hence why I asked for…

I'm not sure where you see a disagreement with section 5.2.2/4 of the standard: "It is implementation-defined whether the lifetime of a parameter ends when the function in which it is defined returns or at the end of the enclosing full-expression." Regardless of where exactly the lifetime of the temporary ends (end of function or end of expression), your example would be correct and not UB. I don't think it is in dis…

If the lifetime of the temporary ended with the function body, the assignment (which reads the temporary via the returned reference) happens afterwards and that's UB. Essentially,

    int const &r = f(3);
and

    int r = f(3);
would both be UB under that implementation-defined case.

The posted article, second row of "common mistakes", describes returning a const reference parameter, when called with a prvalue, as blanket UB.

Finally someone clarified: https://timsong-cpp.github.io/cppwp/class.temporary#6.1

"6.1 A temporary object bound to a reference parameter in a function call persists until the completion of the full-expression containing the call."

So, while the parameter's (the reference "int const &a") lifetime is implementation-defined, the temporary to which that parameter refers to is the full expression of the call. Sanity is restored.

Re: C++ value category cheat-sheet [pdf]

#24
post #22

Earlier quoted context omitted.

I'm not sure where you see a disagreement with section 5.2.2/4 of the standard: "It is implementation-defined whether the lifetime of a parameter ends when the function in which it is defined returns or at the end of the enclosing full-expression." Regardless of where exactly the lifetime of the temporary ends (end of function or end of expression), your example would be correct and not UB. I don't think it is in dis…

If the lifetime of the temporary ended with the function body, the assignment (which reads the temporary via the returned reference) happens afterwards and that's UB. Essentially, int const &r = f(3); and int r = f(3); would both be UB under that implementation-defined case. The posted article, second row of "common mistakes", describes returning a const reference parameter, when called with a prvalue, as blanket UB.…

You're right, good point.

Re: C++ value category cheat-sheet [pdf]

#25

I think the biggest issue in C++ is that you don't have to understand this whole mess to be productive in it. This is also perhaps its greatest strength. Where you have Rust which won't even compile a basic toy program without demonstrating a full understanding of its Ownership model.

It isn't a strength to allow ill-defined programs to silently corrupt your process.

If you don't understand what you are writing, either the compiler (rust-like) or the runtime (script-like) should complain.

C++ usually does neither. I think that's undesirable. Why it does neither makes sense, but I wouldn't call it a strength.

Re: C++ value category cheat-sheet [pdf]

#26
post #5

A comment on the document's design: The low contrast of light gray text on yellow background makes it difficult to read. Black text on white, or dark gray text on white is perfectly acceptable. Another drawback of colored backgrounds is that readers wanting to print out the pdf will consume ink/toner to render the non-white background.

Relevant: http://contrastrebellion.com

Re: C++ value category cheat-sheet [pdf]

#27

Question: it is ok to initialize a string_view from a string literal, right? e.g. std::string_view sv{ "lvalue" }; or auto sv{ "lvalue"sv };

Yes, but never use {} initialization with auto.

Never give advice without telling why, because it's very likely that people will forget it if they don't understand your advice.

Re: C++ value category cheat-sheet [pdf]

#28
post #22

Earlier quoted context omitted.

I'm not sure where you see a disagreement with section 5.2.2/4 of the standard: "It is implementation-defined whether the lifetime of a parameter ends when the function in which it is defined returns or at the end of the enclosing full-expression." Regardless of where exactly the lifetime of the temporary ends (end of function or end of expression), your example would be correct and not UB. I don't think it is in dis…

If the lifetime of the temporary ended with the function body, the assignment (which reads the temporary via the returned reference) happens afterwards and that's UB. Essentially, int const &r = f(3); and int r = f(3); would both be UB under that implementation-defined case. The posted article, second row of "common mistakes", describes returning a const reference parameter, when called with a prvalue, as blanket UB.…

Thanks for digging into this. I'll update that example to be more clear about keeping an lvalue reference to the return value.

Re: C++ value category cheat-sheet [pdf]

#29
post #27

Earlier quoted context omitted.

Yes, but never use {} initialization with auto.

Never give advice without telling why, because it's very likely that people will forget it if they don't understand your advice.

Ok.

  auto i{42}; // std::initializer_list

Re: C++ value category cheat-sheet [pdf]

#30
post #22

Earlier quoted context omitted.

I'm not sure where you see a disagreement with section 5.2.2/4 of the standard: "It is implementation-defined whether the lifetime of a parameter ends when the function in which it is defined returns or at the end of the enclosing full-expression." Regardless of where exactly the lifetime of the temporary ends (end of function or end of expression), your example would be correct and not UB. I don't think it is in dis…

If the lifetime of the temporary ended with the function body, the assignment (which reads the temporary via the returned reference) happens afterwards and that's UB. Essentially, int const &r = f(3); and int r = f(3); would both be UB under that implementation-defined case. The posted article, second row of "common mistakes", describes returning a const reference parameter, when called with a prvalue, as blanket UB.…

Just to help bring things home:

  const int& f(int parameter) { return parameter; }
  const int i = f(42);
Is strictly undefined behavior under the simpler C++03 rules/wording of 5.2.2/4: "The lifetime of a parameter ends when the function in which it is defined returns.")

P0135R0 would loosen the requirements on parameter's lifetime as a means of enabling guaranteed copy elision, in such a way that an implementation could technically decide to make this to have defined behavior (not that I suggest relying on it!)

Post reply on HN