[comp.lang.c] Arrays and structures

jfjr@mitre-bedford.ARPA (Jerome Freedman) (01/20/88)

Suppose I have the following

typedef struct /* I despise structure tags */
  { 
    /* some irrelevant field declarations */
   char string[80];
   int  vector [4];
  } structure_type;


structure_type first_structure,second_structure;

/* The various fields of first_structure get filled */
/* and  somewhere in the code I do this             */

second_structure = first_structure; /* ANSI standard allows this */

Now, tell me about the string and vector fields of second structure.
Since they are arrays then the fields are actually pointers. The
question is: are the string and vector fields of "second_structure"
pointing ad the same addresses as the corresponding fields of
first structure or are they pointing to different areas of
memory into which the contents of the arrays pointed to
in first_structure have been copied(whew - what I meant not
what I said)??

Is the situation different if I change the type declaration to



typedef struct /* I despise structure tags */
  { 
    /* some irrelevant field declarations */
   char *string;
   int  *vector;
  } structure_type;


structure_type first_structure,second_structure;

then I say first_structure.string = "some string";

second_structure = first_structure;




Jerry Freedman, Jr      "Thank you, folks,
jfjr@mitre-bedford.arpa   for those kind applause"
(617)271-4563            



Jerry Freedman, Jr      "Love is staying up all night 
jfjr@mitre-bedford.arpa   with a sick child,
(617)271-4563            or a healthy adult"

chris@mimsy.UUCP (Chris Torek) (01/20/88)

In article <22151@linus.UUCP> jfjr@mitre-bedford.ARPA (Jerome Freedman) writes:
>[Given the (edited) declaration
>struct { char string[80]; int vector [4]; } first_structure,second_structure;
>and, after setting up first_structure, writing]
>second_structure = first_structure; /* ANSI standard allows this */

Yes (as do all modern C compilers).

>Now, tell me about the string and vector fields of second structure.
>Since they are arrays then the fields are actually pointers.

First misconception.  They are arrays; nothing else.  (Conversion
to pointers occurs elsewhere.)

>The question is [hard to grasp]

The contents of each array is copied, as if you had written

	int i;
	for (i = 0; i < 80; i++)
		second_structure.string[i] = first_structure.string[i];
	for (i = 0; i < 4; i++)
		second_structure.vector[i] = first_structure.vector[i];

Note that uninitialised data may cause a trap:

	f1()
	{
		struct goo { char a, b, c } g1, g2;
		g2.a = g1.a;	/* illegal (g1.a not set) */
		g2 = g1;	/* illegal (g1 not set) */
	}
	f2()
	{
		struct yuk { char str[40] } y1, y2;

		strcpy(y1.str, "hi");
		y2 = y1;	/* illegal! (y1.str[3..39] not set) */
				/* can someone check and make *sure*? */
	}

(this is something I had not considered in the `structure copy vs.
structure comparison' debate).

>Is the situation different if I change the type declaration to
(edited)
>struct { char *string; int *vector; } first_structure, second_structure;

Yes, the situation is quite different, but the operation of the
structure assignment is likewise described easily:

	Each element of the structure is copied entire.
	Holes may or may not be copied.
	Elements which are unions are copied `bitwise' in such
		a way as not to cause a trap.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

ok@quintus.UUCP (Richard A. O'Keefe) (01/20/88)

In article <22151@linus.UUCP>, jfjr@mitre-bedford.ARPA (Jerome Freedman) writes:
> Suppose I have the following
> typedef struct
>   { 
>     /* some irrelevant field declarations */
>    char string[80];
>    int  vector [4];
>   } structure_type;
> 
> Now, tell me about the string and vector fields of second structure.
> Since they are arrays then the fields are actually pointers.

Wrong.  Since they are arrays, the fields are actually ARRAYS.
When you *MENTION* an array-valued field, as in
	structure_type Foobaz;
	.... Foobaz.string ...
you get a pointer, just like if you mention ANY array you get a pointer.

If you declare
	structure_type destination, source;
	...
	destination = source;
then the contents of the two fields (80*sizeof (char) bytes of string[]
and 4*sizeof (int) bytes of vector[]) are moved.  No pointers are moved,
copied or changed, because there aren't any pointers.

> Is the situation different if I change the type declaration to
> ...
>    char *string;
>    int  *vector;

Yes.  If you declare arrays, you get arrays.  If you declare pointers
you get pointers.

The easiest way to answer questions like this is to type in a tiny
example and ask your C compiler.
	cc -S foobaz.c			-- UNIX
	/* look at foobaz.s */

	cc foobaz/list/machine_code	-- VMS
	/* look at foobaz.lst */

On other systems, you may have to ask a debugger.

tainter@ihlpg.ATT.COM (Tainter) (01/21/88)

In article <22151@linus.UUCP>, jfjr@mitre-bedford.ARPA (Jerome Freedman) writes:

> Suppose I have the following

> typedef struct /* I despise structure tags */
>   { 
>     /* some irrelevant field declarations */
>    char string[80];
>    int  vector [4];
>   } structure_type;


> structure_type first_structure,second_structure;

> /* The various fields of first_structure get filled */
> /* and  somewhere in the code I do this             */

> second_structure = first_structure; /* ANSI standard allows this */

> Now, tell me about the string and vector fields of second structure.
> Since they are arrays then the fields are actually pointers.

I know of only one implementation of C where this is the case.  In all the
others arrays are inline contiguous elements of the array.  That one
implementation is for Amdahl IBM clones (big ones, not toys).

In such a scheme the compiler is responsible for generating code to copy
the pointed at array data rather than the pointers and the pointers
should be unique so that subsequent modifications do not modify both.
This is the price they pay for using an unusual, nonintuitive implementation
for arrays.

> Is the situation different if I change the type declaration to
> typedef struct /* I despise structure tags */
>   { 
>     /* some irrelevant field declarations */
>    char *string;
>    int  *vector;
>   } structure_type;

Yes, with this it should copy the pointers, not the pointees :-).

> Jerry Freedman, Jr      "Thank you, folks,

--j.a.tainter

gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/21/88)

In article <22151@linus.UUCP> jfjr@mbunix (Freedman) writes:
>Since they are arrays then the fields are actually pointers.

RONG.  In many circumstances, when used in an expression the
name of an array is converted to a pointer to the first element
of the array.  Also, arrays are not passed as function arguments,
so the corresponding pointer parameter declaration is permitted
to be written as an array parameter declaration, even though
this is misleading.  But an array is NOT a pointer.