[Bug other/89106] cast-to-union documentation incorrect w.r.t. lvalueness
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89106 Martin Sebor changed: What|Removed |Added Status|ASSIGNED|RESOLVED Resolution|--- |FIXED Target Milestone|--- |9.0 --- Comment #7 from Martin Sebor --- Fixed in r268411.
[Bug other/89106] cast-to-union documentation incorrect w.r.t. lvalueness
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89106 --- Comment #6 from Martin Sebor --- Author: msebor Date: Thu Jan 31 02:33:58 2019 New Revision: 268411 URL: https://gcc.gnu.org/viewcvs?rev=268411&root=gcc&view=rev Log: PR other/89106 - cast-to-union documentation incorrect w.r.t. lvalueness gcc/ChangeLog: PR other/89106 * doc/extend.texi (cast to a union): Correct and expand. Modified: trunk/gcc/ChangeLog trunk/gcc/doc/extend.texi
[Bug other/89106] cast-to-union documentation incorrect w.r.t. lvalueness
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89106 Martin Sebor changed: What|Removed |Added Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |msebor at gcc dot gnu.org --- Comment #5 from Martin Sebor --- Created attachment 45570 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45570&action=edit Proposed fix. Okay, I'm fine with referring to a temporary instead. I see what you mean about the lifetime but saying it's unspecified seems unnecessary -- temporaries have a temporary lifetime that extends to the end of the full expression and that presumably is the minimum that should apply here as well. I left the reference to compound literals in place. I think it's still useful (especially because of the lifetime). I did some more testing and clarified that it's a C only feature. Attached is what I've got.
[Bug other/89106] cast-to-union documentation incorrect w.r.t. lvalueness
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89106 --- Comment #4 from Alexander Monakov --- My concern is that the cast does not "create a compound literal": what it creates is an object, more specifically, an unnamed temporary object in automatic storage with unspecified lifetime [1]. A compound literal in function scope similarly creates an unnamed object. Likewise, the "result" of a cast-to-union is that temporary object, taken as rvalue. So to explain it well to users, the documentation would have to say something like: A cast to a union creates a temporary object of the given union type, initialized via a member matching the type of the operand, and taken as rvalue (unlike a compound literal, which yields an lvalue). [1] gcc doesn't seem to emit any gimple clobber statements for such casts, so effectively the lifetime is "entire function scope", but that is likely not intentional
[Bug other/89106] cast-to-union documentation incorrect w.r.t. lvalueness
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89106 --- Comment #3 from Martin Sebor --- Is your concern with mentioning it that it describes the implementation? Let's see how that works in the full text: A cast to union type looks similar to other casts, except that the type specified is a union type. You can specify the type either with the union keyword or with a typedef name that refers to a union. Unlike a compound literal, a cast to a union yields an rvalue like standard casts do. See Compound Literals. This is missing a description of the value of the result of the cast. All that's left after the removal of the mention of compound literals is that it's an rvalue. (The cross-reference to compound literals then doesn't make much sense.) I think it's important to describe what the value of the cast is in the text, and not just by relying on examples. The best way that I can think of is by saying it's an [rvalue of a] compound literal. That's fully specified in the standard and it also is what GCC creates internally: a compound literal whose member that corresponds to the operand is initialized the with the value of the operand. A cast to union type looks similar to other casts, except that the type specified is a union type. You can specify the type either with the union keyword or with a typedef name that refers to a union. A cast to a union actually creates a compound literal with the member whose type matches the type of the operand of the cast initialized with the value of the operand. Unlike a compound literal, however, a cast to a union yields an rvalue like standard casts do. See Compound Literals. Adding another example might help clarify this. Given: union foo { int i; double d; }; int x; double y; union foo a; the following a = (union foo)x; is a shorthand equivalent of a = (union foo){ .i = x }; (It might be worth also showing an example where the cast doesn't work, i.e., when there is no matching type.) I realize this may not resolve your concern about describing the implementation but (IIUC) I think it accurately describes the feature.
[Bug other/89106] cast-to-union documentation incorrect w.r.t. lvalueness
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89106 --- Comment #2 from Alexander Monakov --- I don't think it's appropriate to say "creates a compound literal". My preference would be: Unlike a compound literal, a cast to a union yields an rvalue like standard casts do.
[Bug other/89106] cast-to-union documentation incorrect w.r.t. lvalueness
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89106 Martin Sebor changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2019-01-29 Ever confirmed|0 |1 --- Comment #1 from Martin Sebor --- It does look seem the change went a step too far in describing the feature's similarity to compound literals. It probably should have been limited to removing the mention of a constructor and correcting the part about normal casts yielding an lvalue. I.e., it should have replaced the sentence A cast to union is actually a constructor, not a cast, and hence does not yield an lvalue like normal casts. with one like: A cast to a union creates a compound literal but yields an rvalue like standard casts do. How does that look? (I suspect the part about a constructor in the original text might have been a reference to GCC's internal representation of the cast as a CONSTRUCTOR and didn't have anything to do with C++ constructors because those do yield lvalues.)