C Aggregate Initialization

S.M.Stanziano sue at sfmag.UUCP
Tue Feb 11 01:54:05 AEST 1986


I am taking a survey at Larry Rosler's behest
for the benefit of the ANSI C committee.  Although
this article is LONG, I hope you will plow through
it and let me know if you would be affected by the
proposal that I outline below for initialization of
aggregates (structs, arrays).

The gist of the problem is that most PCC-based
compilers handle some of these initializations
(cases described below) differently from the way
K&R describes them, which is one of the
ways the ANSI committee is considering defining
aggregate initialization.  Furthermore, it is
hard to formalize exactly what PCC-based compilers
are doing.

Consider this declaration:

struct outer {
    struct inner {
	int i[3];
    } a;
    char * b;
};

If you initialize an array of these and include
all of the { }'s, most compilers are happy:

	struct outer a1[] = {
	    { {1, 2, 3}, "hello" },
	    { {4, 5, 6}, "world" }
	};

Problems arise when you omit { }'s:

	struct outer a2[] = {
	    { 1, 2, 3, "hello" },
	    { 4, 5, 6, "world" }
	};

PCC-based compilers complain about this
because they treat the { next to the 1 as the
beginning of a2[0].i, rather than the beginning
of a2[0].

PCC-based compilers currently accept this code, which
is wrong according to K&R:

	struct outer a3[] = {
	    {1, 2, 3}, "hello",
	    {4, 5, 6}, "world"
	};

The correct interpretation, according to K&R, is that
{1,2,3} initializes a3[0].  Thus "hello"
is an attempt to initialize a3[1].i[0],
and that's a type mismatch.

Here's a case where both PCC-based compilers
and K&R would accept the C code, but the
interpretation would be different:

	struct st {
	    int a[3];
	    int b;
	};

	struct sta[] = {
	    { 1 },
	    2
	};

In the PCC interpretation
sta[0].a[0] is 1 and sta[0].b is 2.
In the K&R interpretation,
sta[0].a[0] is 1 and sta[1].a[0] is 2.
(sta[0].a[1], sta[0].a[2], and sta[0].b
are all zero.)

Summary:
	1. PCC-based compilers handle initializations
	   with all { }'s as K&R says.
	2. If the initialization lists all members and omits
	   all (but the outermost) { }'s PCC and K&R agree.
	3. When some members are missing and some { }'s are
	   omitted, there are three possible conflicts:
	   a. PCC rejects, K&R accepts
	   b. PCC accepts, K&R rejects
	   c. both accept and give different behavior


====== QUESTION TO YOU =====

Cases b and c WILL BREAK your code.  Do you have any
initializations that would be broken by the K&R
interpretation?  If so, would such a change cause
you serious trouble.  (Case c is more worrisome than
Case b because it is silently different.)

I particularly want to hear from people with Case c
examples or who otherwise consider this a serious
compatibility problem.

I will welcome (preferably short) code
examples that exhibit compatibility problems.
Please do a "cc -P ..." and send me the .i file.

David Kristol, AT&T-ISL
attunix!dmk
(201) 522-6162



More information about the Comp.lang.c mailing list