[Bug other/89106] cast-to-union documentation incorrect w.r.t. lvalueness

2019-01-30 Thread msebor at gcc dot gnu.org
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

2019-01-30 Thread msebor at gcc dot gnu.org
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

2019-01-30 Thread msebor at gcc dot gnu.org
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

2019-01-30 Thread amonakov at gcc dot gnu.org
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

2019-01-30 Thread msebor at gcc dot gnu.org
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

2019-01-30 Thread amonakov at gcc dot gnu.org
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

2019-01-29 Thread msebor at gcc dot gnu.org
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.)