Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

array and struct initializations.

1 view
Skip to first unread message

Eli Lopez

unread,
Nov 6, 1993, 3:57:11 PM11/6/93
to

Hi,
I have encountered two different behavior in regarding the code below
(comparing the GNX 32K compiler and GCC).
I cannot put my hands on a copy of the ANSI std, so don't give me section
numbers, but quotes. thanks.


typedef struct {
int a;
int b;
}two_ints;

two_ints ar1[2][3] = { /* OK */
1, 1,
2, 2,
3, 3,
4, 4,
5, 5,
6, 6,
};

two_ints ar2[2][3] = { /* OK */
{ {1, 1},
{2, 2},
{3, 3}},
{ {4, 4},
{5, 5},
{6, 6}},
};


two_ints ar3[2][3] = { /* OK for GNX */
{1, 1},
{2, 2},
{3, 3},
{4, 4},
{5, 5},
{6, 6},
};


two_ints ar4[2][3]= { /* OK for GCC*/
{ 1, 1,
2, 2,
3, 3 } ,
{ 4, 4,
5, 5,
6, 6 },
};

two_ints ar5[2][3] = { /* this is wrong */
{1,2,3},
{1,2,3},
{1,2,3},
{1,2,3},
};


ar1 and ar2 are OK for everyone.
ar3 can be compiled only on GNX, and ar4 only on GCC,
The error: "excess elements in aggregate initializer after `arx' ".
ar5 is an error everywhere.
Apparently, the GCC looks for a line initialization when it finds the braces,
while the GNX looks for an element in this case.

In the literature I can find no refference to which is correct. It seems undefined.
Any idea?

Inbal.

-----------------------------------------------------------
Inbal Cohen-Hamo National Semiconductor, Tel Aviv, Israel
Mail : cin...@taux01.nsc.com
-----------------------------------------------------------

Norman Diamond

unread,
Nov 7, 1993, 7:39:57 PM11/7/93
to
In article <1993Nov6.2...@berlioz.nsc.com> cel...@berlioz.nsc.com (Eli Lopez) writes:
>typedef struct { int a; int b; }two_ints;

>two_ints ar1[2][3] = { /* OK */
> 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
>};

"Otherwise, only enough initializers from the list are taken to account for
the members of the subaggregate or the first member of the contained union;
any remaining initializers are left to initialize the next member of the
aggregate of which the current subaggregate or contained union is a part."

>two_ints ar2[2][3] = { /* OK */
> { {1, 1}, {2, 2}, {3, 3}},
> { {4, 4}, {5, 5}, {6, 6}},
>};

"If the initializer of a subaggregate or contained union begins with a left
brace, the initializers enclosed by that brace and its matching right brace
initialize the members of the subaggregate or the first member of the
contained union."

>two_ints ar3[2][3] = { /* OK for GNX */
> {1, 1}, {2, 2}, {3, 3},
> {4, 4}, {5, 5}, {6, 6},
>};

{1, 1} initializes ar3[0]. The first two elements, ar3[0][0].a and
ar3[0][0].b, get their values from here. Next, "If there are fewer
initializers in a brace-enclosed list than there are members of an aggregate,
the remainder of the aggregate shall be initalized implicitly the same as
objects that have static storage duration." So ar3[0][1].a, ar3[0][1].b,
ar3[0][2].a, and ar3[0][2].b are all initialized to zeros.

{2, 2} initializes ar3[1] in the same manner.

{3, 3} etc. violate a constraint. "There shall be no more initializers in
an initializer list than there are objects to be initialized." A diagnostic
is required, but GNX is allowed to proceed to execute your program if it
wishes, in addition to issuing the required diagnostic.

>two_ints ar4[2][3]= { /* OK for GCC*/
> { 1, 1, 2, 2, 3, 3 } ,
> { 4, 4, 5, 5, 6, 6 },
>};

"If the aggregate contains members that are aggregates or unions, or if the
first members of a union is an aggregate or union, the rules apply
recursively to the subaggregates or contained unions." So the first
brace-enclosed list initializes all of ar4[0] and the second brace-enclosed
list initializes all of ar4[1], recursively using the rule that applied to
your first example. If GNX rejected this, GNX is not conforming.

>two_ints ar5[2][3] = { /* this is wrong */
> {1,2,3}, {1,2,3}, {1,2,3}, {1,2,3},
>};

It is wrong for the same reason as your third example.

>In the literature I can find no refference to which is correct.

One might suppose that the standard is part of the literature.
--
<< If this were the company's opinion, I would not be allowed to post it. >>
A program in conformance will not tend to stay in conformance, because even if
it doesn't change, the standard will. Force = program size * destruction.
Every technical corrigendum is met by an equally troublesome new defect report.

Larry Jones

unread,
Nov 8, 1993, 10:35:52 AM11/8/93
to
In article <1993Nov6.2...@berlioz.nsc.com>, cel...@berlioz.nsc.com (Eli Lopez) writes:
>
> I have encountered two different behavior in regarding the code below
> (comparing the GNX 32K compiler and GCC).
> [code using initializers with varying degrees of elided braces]

Actually, the Rationale is more appropriate:

Various implementations have parsed aggregate initializers with
partially elided braces differently. The Standard has
reaffirmed the (top-down) parse described in the Base Document.
Although the construct is allowed, and its parse well defined,
the Committee urges programmers to avoid partially elided
initializers: such initializations can be quite confusing to
read.

QUIET CHANGE
Code which relies on a bottom-up parse of aggregate
initializers with partially elided braces will not
yield the expected initialized object.

Unfortunately, Johnson's Portable C Compiler (pcc) -- which was the
basis for most pre-ANSI C compilers -- used bottom-up parsing which was
most natural for its Yacc parser. Thus, most pre-ANSI C compilers
parsed initializers with partially elided braces incorrectly (according
to K&R and ANSI/ISO). I fully concur with the committee's advice:
either use all the braces or none of them.
----
Larry Jones, SDRC, 2000 Eastman Dr., Milford, OH 45150-2789 513-576-2070
larry...@sdrc.com
You can never really enjoy Sundays because in the back of your
mind you know you have to go to school the next day. -- Calvin

0 new messages