[net.lang.c] Structure question

emacs@vger.UUCP (05/20/85)

Could someone please inform me what the hell I am doing wrong.  The
subject is auto-initialization of structures.  Here is a simple program
that trys to initialize the stucture, and the associated error
message.  If I take one of K&R's examples (pg 124, last half page),
I get the same error.
BTW-This is 4.2bsd.

=====

/* Structure test */

#include <stdio.h>


main() {

	static char *text[] = { "Fred", "Wilma", "Barney", "Betty" };
	struct l {
		int a;
		int b;
		char *c;
		int d; 
		 } e = { 0, 1, text[0], 4 };
	
	printf("Fred is married to Wilma, Barney to Betty...\n");

}

=====
% cc t.c
"t.c", line 14: no automatic aggregate initialization
"t.c", line 14: warning: illegal combination of pointer and integer, op =

Why can I not automatically initialize.  K&R says I can.  This must
and has to be a real simple fix.  What am I doing wrong?

-- 
---------------------          ...Lying on the beach in the sun...
|                   |-------------------------------------------------------
| Michael E. Dove   | Usenet: ucbvax!hplabs!pesnta!parallel!ucscv!emacs    |
| CIS Consultant    |         ihnp4!sun!parallel!ucscv!emacs               |
| UC Santa Cruz, CA | CSNet:  emacs@ucsc.csnet                             |
|                   | Arpa:   emacs%ucsc.csnet@csnet-relay.arpa            |
----------------------------------------------------------------------------
--

teach0@whuts.UUCP (CTD_STUDENT0.) (05/23/85)

> Could someone please inform me what the hell I am doing wrong.  The
> subject is auto-initialization of structures.  Here is a simple program
> that trys to initialize the stucture, and the associated error
> message.  If I take one of K&R's examples (pg 124, last half page),
> I get the same error.
> BTW-This is 4.2bsd.
> 
> =====
> 
> /* Structure test */
> 
> #include <stdio.h>
> 
> 
> main() {
> 
> 	static char *text[] = { "Fred", "Wilma", "Barney", "Betty" };
> 	struct l {
> 		int a;
> 		int b;
> 		char *c;
> 		int d; 
> 		 } e = { 0, 1, text[0], 4 };
> 	
> 	printf("Fred is married to Wilma, Barney to Betty...\n");
> 
> }
> 
> =====
> % cc t.c
> "t.c", line 14: no automatic aggregate initialization
> "t.c", line 14: warning: illegal combination of pointer and integer, op =
> 
Aggregates (arrays, structures, unions) can only be initialized if
they are declared static or external. A simple:

	static struct l{ .........

will do.

--

Fred Eng
AT&T Bell Laboratories

gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (05/24/85)

> "t.c", line 14: no automatic aggregate initialization

You're not doing anything wrong; that's the way it is.
This is fixed in the ANSI C specs.

moss@Brl.ARPA (Gary S. Moss (AMXBR-VLD-V)) (05/24/85)

Automatic initializations are not permitted on aggregates, this reeks
of prejudice, however, often making the structure static provides
the same functionality (no flames, I said "often").  Or you can wait
for ANSI to fix it.
-moss

schwrtze@csd2.UUCP (Eric Schwartz group) (05/24/85)

its an implementation nightmare to have to init structures/arrays/unions
Remember automatic means that this stuff is on the stack, and your subroutine
will have to spend time doing the init (which should have just been static)
I agree it should be allowed but I won't use it.

Hedley Rainnie.

faustus@ucbcad.UUCP (Wayne A. Christopher) (05/29/85)

> its an implementation nightmare to have to init structures/arrays/unions

That is another thing that I would like to see in standard C -- initialization
of unions. You can't do it now, presumably because there are problems with
deciding which element you want to assign it to (although I can't really
see where the problems would come in...). If you write something like

union foo {
	int a;
	char *b;
	long c;
} bar[] = {
	{ 57 } ,
	{ (long) 76365 } ,
	{ "Hey, here we are" }
} ;

to initialize several unions, the compiler shouldn't have any trouble sseing
what you mean, right?

	Wayne

dan@mgweed.UUCP (Daniel Gray) (05/30/85)

If my memory serves me correctly, The compiler will allocate only
enough space for the largest element in the union. There for, it is
the responsibility of the programmer to remember what is in the union
and work with it accordingly. If you want to initialize something to
specific values, I suggest that you deal with struc[tures]. Only in
structures can all of the elements reside concurrently.


Daniel Gray
ihnp4!mgweed!mgbase!dan

td@alice.UUCP (Tom Duff) (05/30/85)

It is very difficult to formulate a reasonable rule for union
initialization.  The ANSI rule (initializers apply to the first member)
is just a kludge.  The `match the types' rule plays fast and loose
with C's type-matching rules.  Consider ucbcat!faustus's example
(here simplified):
union{
	int a;
	long b;
}c[]={
	57,
	(long)76365
};
ucbcat!faustus no doubt expects 57 to initialize a and 76365 to
initialize b.  But 57 is a legal initializer for b and (long)76365
is a legal initializer for a.
So the `match the types' rule is not a simple patch to the language,
but requires a completely different set of type-matching rules than
already exist.  This is, to say the least, unsatisfactory.

Furthermore, this scheme cannot even be made to work.  The following
example should indicate one reason:

union{
	int a;
	struct{
		int :16;
		int b;
	}c;
}d={5};

faustus@ucbcad.UUCP (Wayne A. Christopher) (06/01/85)

> It is very difficult to formulate a reasonable rule for union
> initialization.  The ANSI rule (initializers apply to the first member)
> is just a kludge.  The `match the types' rule plays fast and loose
> with C's type-matching rules.  Consider ucbcat!faustus's example
> (here simplified):
> union{
> 	int a;
> 	long b;
> }c[]={
> 	57,
> 	(long)76365
> };

Well, it wasn't quite that -- I had only one value in the initialization.
That's all you need, since they will overwrite each other anyway.

> ucbcat!faustus no doubt expects 57 to initialize a and 76365 to
> initialize b.  But 57 is a legal initializer for b and (long)76365
> is a legal initializer for a.

But if you had a choice it would make sense to match the types, or at
least do them in the order that they are written. If you only give one
value, then there might be some problem if you had a long and a short,
and it made a difference which one you filled in (e.g, if you filled in
the long it wouldn't have the same value as the short). In that case,
all you need is some coherent rule for what is going to happen... I
think that the "first element" rule is good enough for most purposes.

> Furthermore, this scheme cannot even be made to work.  The following
> example should indicate one reason:
> 
> union{
> 	int a;
> 	struct{
> 		int :16;
> 		int b;
> 	}c;
> }d={5};

This will work, because you will never be able to assign the integer 5 to
the structure. If you wanted to assign something to the structure you
would have to write " ... } d = { 5, { 53, 474 } } ;", which is probably
useless, because unless you know which member of the union you will use
first there's no point in initializing any of them...

	Wayne