diff mbox

doc fix for c/71560 - union compound literal initializes wrong union field

Message ID 57770316.70800@gmail.com
State New
Headers show

Commit Message

Martin Sebor July 1, 2016, 11:56 p.m. UTC
The bug points out a couple of conformance problems in the GCC
manual where is discusses compound literals and casts to unions
and says that a compound literal is equivalent to a cast.  It
isn't because a compound literal is an lvalue but a cast yields
an rvalue.

The attached patch corrects this error and adds some clarifying
text to illustrate the differences.

Martin

Comments

Sandra Loosemore July 3, 2016, 11:22 p.m. UTC | #1
On 07/01/2016 05:56 PM, Martin Sebor wrote:
> The bug points out a couple of conformance problems in the GCC
> manual where is discusses compound literals and casts to unions
> and says that a compound literal is equivalent to a cast.  It
> isn't because a compound literal is an lvalue but a cast yields
> an rvalue.
>
> The attached patch corrects this error and adds some clarifying
> text to illustrate the differences.

This looks OK modulo some markup problems.

> @@ -1905,18 +1906,23 @@ such an initializer, as shown here:
>  char **foo = (char *[]) @{ "x", "y", "z" @};
>  @end smallexample
>
> -Compound literals for scalar types and union types are
> -also allowed, but then the compound literal is equivalent
> -to a cast.
> +Compound literals for scalar types and union types are also allowed.  In
> +the following example the variable @var{i} is initialized to the value

s/@var/@code/

(@var is for metasyntactic variables, not program variables.)

> @@ -1934,22 +1940,21 @@ static int z[] = @{1, 0, 0@};
>
>  In C, a compound literal designates an unnamed object with static or
>  automatic storage duration.  In C++, a compound literal designates a
> -temporary object, which only lives until the end of its
> -full-expression.  As a result, well-defined C code that takes the
> -address of a subobject of a compound literal can be undefined in C++,
> -so the C++ compiler rejects the conversion of a temporary array to a pointer.
> -For instance, if the array compound literal example above appeared
> -inside a function, any subsequent use of @samp{foo} in C++ has
> -undefined behavior because the lifetime of the array ends after the
> -declaration of @samp{foo}.
> +temporary object that only lives until the end of its full-expression.
> +As a result, well-defined C code that takes the address of a subobject
> +of a compound literal can be undefined in C++, so G++ rejects
> +the conversion of a temporary array to a pointer.  For instance, if
> +the array compound literal example above appeared inside a function,
> +any subsequent use of @samp{foo} in C++ would have undefined behavior
> +because the lifetime of the array ends after the declaration of @samp{foo}.
>
> -As an optimization, the C++ compiler sometimes gives array compound
> -literals longer lifetimes: when the array either appears outside a
> -function or has const-qualified type.  If @samp{foo} and its
> -initializer had elements of @samp{char *const} type rather than
> -@samp{char *}, or if @samp{foo} were a global variable, the array
> -would have static storage duration.  But it is probably safest just to
> -avoid the use of array compound literals in code compiled as C++.
> +As an optimization, G++ sometimes gives array compound literals longer
> +lifetimes: when the array either appears outside a function or has
> +a const-qualified type.  If @samp{foo} and its initializer had elements
> +of type @samp{char *const} rather than @samp{char *}, or if @samp{foo}
> +were a global variable, the array would have static storage duration.
> +But it is probably safest just to avoid the use of array compound
> +literals in C++ code compiled.

I think it would be more appropriate to use @code rather than @samp 
markup throughout this discussion, since foo, char*, etc are "entire 
syntactic tokens", per the texinfo manual.

-Sandra the nit-picky
diff mbox

Patch

PR c/71560 - union compound literal initializes wrong union field

gcc/ChangeLog:
2016-06-23  Martin Sebor  <msebor@redhat.com>

	PR c/71560
	* doc/extend.texi (Compound Literals): Correct and clarify.
	(Cast to Union): Same.

Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi	(revision 237617)
+++ gcc/doc/extend.texi	(working copy)
@@ -1863,15 +1863,16 @@  foo (float f, float g)
 @cindex compound literals
 @c The GNU C name for what C99 calls compound literals was "constructor expressions".
 
-ISO C99 supports compound literals.  A compound literal looks like
-a cast containing an initializer.  Its value is an object of the
-type specified in the cast, containing the elements specified in
-the initializer; it is an lvalue.  As an extension, GCC supports
-compound literals in C90 mode and in C++, though the semantics are
-somewhat different in C++.
+A compound literal looks like a cast of a brace-enclosed aggregate
+initializer list.  Its value is an object of the type specified in
+the cast, containing the elements specified in the initializer.
+Unlike the result of a cast, a compound literal is an lvalue.  ISO
+C99 and later support compound literals.  As an extension, GCC
+supports compound literals also in C90 mode and in C++, although
+as explained below, the C++ semantics are somewhat different.
 
-Usually, the specified type is a structure.  Assume that
-@code{struct foo} and @code{structure} are declared as shown:
+Usually, the specified type of a compound literal is a structure.  Assume
+that @code{struct foo} and @code{structure} are declared as shown:
 
 @smallexample
 struct foo @{int a; char b[2];@} structure;
@@ -1905,18 +1906,23 @@  such an initializer, as shown here:
 char **foo = (char *[]) @{ "x", "y", "z" @};
 @end smallexample
 
-Compound literals for scalar types and union types are
-also allowed, but then the compound literal is equivalent
-to a cast.
+Compound literals for scalar types and union types are also allowed.  In
+the following example the variable @var{i} is initialized to the value
+@code{2}, the result of incrementing the unnamed object created by
+the compound literal.
 
+@smallexample
+int i = ++(int) @{ 1 @};
+@end smallexample
+
 As a GNU extension, GCC allows initialization of objects with static storage
-duration by compound literals (which is not possible in ISO C99, because
+duration by compound literals (which is not possible in ISO C99 because
 the initializer is not a constant).
-It is handled as if the object is initialized only with the bracket
-enclosed list if the types of the compound literal and the object match.
-The initializer list of the compound literal must be constant.
+It is handled as if the object were initialized only with the brace-enclosed
+list if the types of the compound literal and the object match.
+The elements of the compound literal must be constant.
 If the object being initialized has array type of unknown size, the size is
-determined by compound literal size.
+determined by the size of the compound literal.
 
 @smallexample
 static struct foo x = (struct foo) @{1, 'a', 'b'@};
@@ -1934,22 +1940,21 @@  static int z[] = @{1, 0, 0@};
 
 In C, a compound literal designates an unnamed object with static or
 automatic storage duration.  In C++, a compound literal designates a
-temporary object, which only lives until the end of its
-full-expression.  As a result, well-defined C code that takes the
-address of a subobject of a compound literal can be undefined in C++,
-so the C++ compiler rejects the conversion of a temporary array to a pointer.
-For instance, if the array compound literal example above appeared
-inside a function, any subsequent use of @samp{foo} in C++ has
-undefined behavior because the lifetime of the array ends after the
-declaration of @samp{foo}.  
+temporary object that only lives until the end of its full-expression.
+As a result, well-defined C code that takes the address of a subobject
+of a compound literal can be undefined in C++, so G++ rejects
+the conversion of a temporary array to a pointer.  For instance, if
+the array compound literal example above appeared inside a function,
+any subsequent use of @samp{foo} in C++ would have undefined behavior
+because the lifetime of the array ends after the declaration of @samp{foo}.
 
-As an optimization, the C++ compiler sometimes gives array compound
-literals longer lifetimes: when the array either appears outside a
-function or has const-qualified type.  If @samp{foo} and its
-initializer had elements of @samp{char *const} type rather than
-@samp{char *}, or if @samp{foo} were a global variable, the array
-would have static storage duration.  But it is probably safest just to
-avoid the use of array compound literals in code compiled as C++.
+As an optimization, G++ sometimes gives array compound literals longer
+lifetimes: when the array either appears outside a function or has
+a const-qualified type.  If @samp{foo} and its initializer had elements
+of type @samp{char *const} rather than @samp{char *}, or if @samp{foo}
+were a global variable, the array would have static storage duration.
+But it is probably safest just to avoid the use of array compound
+literals in C++ code compiled.
 
 @node Designated Inits
 @section Designated Initializers
@@ -2140,11 +2145,11 @@  case 1...5:
 @cindex cast to a union
 @cindex union, casting to a
 
-A cast to union type is similar to other casts, except that the type
+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
-@code{union @var{tag}} or with a typedef name.  A cast to union is actually
-a constructor, not a cast, and hence does not yield an lvalue like
-normal casts.  (@xref{Compound Literals}.)
+@code{union @var{tag}} or with a typedef name.  A cast to union actually
+creates a compound literal and yields an lvalue, not an rvalue like true
+casts do.  (@xref{Compound Literals}.)
 
 The types that may be cast to the union type are those of the members
 of the union.  Thus, given the following union and variables: