@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;
You can also construct an array, though this is dangerous in C++, as
explained below. If all the elements of the compound literal are
-(made up of) simple constant expressions, suitable for use in
+(made up of) simple constant expressions suitable for use in
initializers of objects of static storage duration, then the compound
literal can be coerced to a pointer to its first element and used in
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 @code{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'@};
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}.
-
-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++.
+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 @code{foo} in C++ would have undefined behavior
+because the lifetime of the array ends after the declaration of @code{foo}.
+
+As an optimization, G++ sometimes gives array compound literals longer
+lifetimes: when the array either appears outside a function or has
+a @code{const}-qualified type. If @code{foo} and its initializer had
+elements of type @code{char *const} rather than code{char *}, or if
+@code{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.
@node Designated Inits
@section Designated Initializers
@cindex cast to a union
@cindex union, casting to a
-A cast to union type is 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}.)
+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
+@code{union} keyword or with a @code{typedef} name that refers to
+a union. A cast to a 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: