This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Semantics of CONSTRUCTOR tree nodes
- From: "Joseph S. Myers" <jsm28 at cam dot ac dot uk>
- To: Per Bothner <per at bothner dot com>
- Cc: <gcc at gcc dot gnu dot org>
- Date: Tue, 27 Nov 2001 01:31:43 +0000 (GMT)
- Subject: Re: Semantics of CONSTRUCTOR tree nodes
On Mon, 26 Nov 2001, Per Bothner wrote:
> >What are the exact semantics of CONSTRUCTOR tree nodes meant to be? I
> >think that they are not meant to be the same as C99 compound literals -
> >
> I don't know what 'C99 compound literals' are - but CONSTRUCTORs are
> meant to be encode a brace-initializer-lists in standard C.
>
> A CONSTRUCTOR is an rvalue, not a variable. It has a type.
Compound literals are
( type-name ) { initializer-list }
( type-name ) { initializer-list , }
They are lvalues, described in C99 6.5.2.5. GCC uses this syntax for
something that used to be called "constructor expressions", that is
similar but not the same. It uses CONSTRUCTOR tree nodes to represent
them.
> >and so compound literals ought to use a new tree node which wraps around a
> >CONSTRUCTOR and provides the appropriately initialised object (an
> >anonymous VAR_DECL initialised by the CONSTRUCTOR, probably) with
> >appropriate storage duration required by C99, but some questions about the
> >CONSTRUCTORs:
> >
> That sounds wrong.
Given the nature of compound literals as "an unnamed object whose value is
given by the initializer list, which is an lvalue, and given that
CONSTRUCTORs are rvalues, I don't see a better way. If CONSTRUCTORs only
represent the initializer list, some other tree node is needed to
represent the object that is a compound literal.
> >1. Is it intended that multiple CONSTRUCTORs with identical contents can
> >share the same memory?
> >
> The question is meaningless. CONSTRUCTORs do not have memory.
> It is like asking if multiple PLUS_EXPRs can share the same memory.
In certain cases - not all, though in C99 it should be all - GCC treats
compound literals as lvalues, and allows their addresses (that is,
addresses of these objects represented as CONSTRUCTORs) to be taken. In
such cases, it does seem to share the memory, see e.g. PR c/4787.
> >2. Is it undefined behavior if the memory occupied by a CONSTRUCTOR gets
> >modified at runtime?
> >
> Likewise.
gcc.c-torture/execute/20000722-1.c (XFAIL) is a testcase showing problems
associated with the memory being modified.
> >3. What is the storage duration of memory occupied by a CONSTRUCTOR?
> >
> What is the storage duration of the memory occupied by integer 5?
The address of compound literals can be taken - and they are represented
as CONSTRUCTORs - so for them the question is meaningful.
6.5.2.5 Compound literals
Constraints
[#1] The type name shall specify an object type or an array
of unknown size, but not a variable length array type.
[#2] No initializer shall attempt to provide a value for an
object not contained within the entire unnamed object
specified by the compound literal.
[#3] If the compound literal occurs outside the body of a
function, the initializer list shall consist of constant
expressions.
Semantics
[#4] A postfix expression that consists of a parenthesized
type name followed by a brace-enclosed list of initializers
is a compound literal. It provides an unnamed object whose
value is given by the initializer list.80)
80)Note that this differs from a cast expression. For
example, a cast specifies a conversion to scalar types or
void only, and the result of a cast expression is not an
lvalue.
[#5] If the type name specifies an array of unknown size,
the size is determined by the initializer list as specified
in 6.7.8, and the type of the compound literal is that of
the completed array type. Otherwise (when the type name
specifies an object type), the type of the compound literal
is that specified by the type name. In either case, the
result is an lvalue.
[#6] The value of the compound literal is that of an unnamed
object initialized by the initializer list. If the compound
literal occurs outside the body of a function, the object
has static storage duration; otherwise, it has automatic
storage duration associated with the enclosing block.
[#7] All the semantic rules and constraints for initializer
lists in 6.7.8 are applicable to compound literals.81)
81)For example, subobjects without explicit initializers are
initialized to zero.
[#8] String literals, and compound literals with const-
qualified types, need not designate distinct objects.82)
82)This allows implementations to share storage for string
literals and constant compound literals with the same or
overlapping representations.
(Examples omitted.)
--
Joseph S. Myers
jsm28@cam.ac.uk