Path: utzoo!utgpu!water!watmath!clyde!cbosgd!ihnp4!homxb!mtuxo!mtgzz!drutx!druco!connors
From: connors@druco.ATT.COM (ConnorsPA)
Newsgroups: comp.lang.c
Subject: Data initialization -- a major problem.
Keywords: C, compilers
Message-ID: <2422@druco.ATT.COM>
Date: 11 Dec 87 05:51:43 GMT
Distribution: comp
Organization: AT&T, Denver, CO
Lines: 91


There seems to be a major inconsistency in how various C compilers
assume data initializations to be defined.

EXAMPLE 1
--------

Either:
	int a = 1;
or:
	int a = {1};

is a valid way of initializing the integer 'a' to 1.
(See page 198 of the "C Programming Language" White Book.)

No problem with this.

But what about:
	int a[2] = { 1, 2 };
or:
	int a[2] = { {1}, {2} };
with the intention of initializing the array 'a' such that a[0]=1, a[1]=2 ?

Here, some compilers will reject the second form,
with some such message as "initialization alignment error".
Others will accept it and initialize the array in the intended way.

EXAMPLE 2
---------

A much more serious problem occurs in the following example,
abstracted from some real code which had portability problems,
and where different compilers will SILENTLY interpret the data
in different ways:

---------------------------------------------------------------------------
struct s1 {
		int a;
		int b;
		int c;
	  };

struct s2 {
		struct s1 sarr[2];
	 };

struct s2 SS[2] = {
			{2, 3},		/* ROW A */
			{4, 5}		/* ROW B */
		  };
---------------------------------------------------------------------------

The difference between compilers is that the two rows of data, A and B,
commented in the above section of code, are interpreted in two different ways. 
Looking at the assembler generated shows that the initializations
follow one of the following methods:

		METHOD A	METHOD B
		--------	--------
SS[0].sarr[0].a = 2;		= 2;
SS[0].sarr[0].b = 3;		= 3;
SS[0].sarr[0].c = 0;		= 0;
SS[0].sarr[1].a = 4;		= 0;
SS[0].sarr[1].b = 5;		= 0;
SS[0].sarr[1].c = 0;		= 0;
SS[1].sarr[0].a = 0;		= 4;
SS[1].sarr[0].b = 0;		= 5;
SS[1].sarr[0].c = 0;		= 0;
SS[1].sarr[1].a = 0;		= 0;
SS[1].sarr[1].b = 0;		= 0;
SS[1].sarr[1].c = 0;		= 0;

In Method A, the compiler thinks that the two rows of data
are for SS[0].sarr[0] and SS[0].sarr[1].

In Method B, the compiler thinks that the two rows of data
are for SS[0].sarr[0] and SS[1].sarr[0].

Naively, one would expect that only one of these two forms
is the "correct" one. But which?

After a careful perusal of the White Book, I have come up
with no clear answer. I can generate several other variations
on the same problem. In general, there seems to be a lack of precision
about the interpretation of braces inside data initializations.

Whatever the answer is, we are left with the problem
that current compilers (I have looked at eight) operate under
different assumptions.

But what IS the answer?