[net.lang.c] Portability Question

Schauble@MIT-MULTICS.ARPA (Paul Schauble) (11/05/85)

Could people please comment on the portability of this structure?  If
it's not, why not and how does one set up a structure where one needs to
access the items both by pointer/subscript in a loop and by individual
name in inline code?

    struct x {something};
    struct x *ip;

    struct
      {
          struct x a;
          struct x b;
          struct x c;
          struct x d;
          struct x e;
      }
          index;

    y = index.a.whatever;
    z = index.c.whatever;

    ip = (struct x *)&index;
    ...
    w = ip[i].whatever;

---------------------------------

Flames accepted...the temperature here hasn`t gone over 90 in aweek
now...

              Paul Schauble
              Schauble at MIT-Multics.ARPA
              ...but really in Phoenix, AZ

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

>     struct x {something};
>     struct x *ip;
> 
>     struct
>       {
>           struct x a;
>           struct x b;
>           struct x c;
>           struct x d;
>           struct x e;
>       }
>           index;
> 
>     y = index.a.whatever;
>     z = index.c.whatever;
> 
>     ip = (struct x *)&index;
>     ...
>     w = ip[i].whatever;

That is not guaranteed to work, primarily because there
may be padding between the members of `index'.  However,
it is unlikely that there would be padding since it
would normally be contained within a `struct x'.

Consider the following less elaborate code:

	struct x {something};

	struct x array[5];
	#define	a array[1]
	#define	b array[2]
	#define	c array[3]
	#define	d array[4]
	#define	e array[5]

	y = a.whatever;
	z = c.whatever;
	...
	w = array[i].whatever;

gwyn@BRL.ARPA (VLD/VMB) (11/06/85)

Oops, of course that should have been
	#define a array[0]
etc.  Been dealing with Fortran too
much recently.

jsdy@hadron.UUCP (Joseph S. D. Yao) (11/06/85)

In article <2834@brl-tgr.ARPA> Schauble@MIT-MULTICS.ARPA (Paul Schauble) writes:
>Could people please comment on the portability of this structure?  If
>it's not, why not and how does one set up a structure where one needs to
>access the items both by pointer/subscript in a loop and by individual
>name in inline code?
[ Compressed: ]
>    struct x {something};
>    struct x *ip;
>    struct {
>          struct x a; struct x b; struct x c; struct x d; struct x e;
>    } index;
>    y = index.a.whatever; z = index.c.whatever;
>    ip = (struct x *)&index; ...; w = ip[i].whatever;

Paul, it's too late for me to flame.  But you should realize that
just because a struct of structs and an array of structs are packed
the same on most machines doesn't mean they always will be!  Drop
those wonderfully descriptive terms 'a', 'b', etc., and say
instead, e.g.:
	#define NOTHING	0
	#define	HYDROGEN 1
	#define	HELIUM	2
	#define LITHIUM	3
	#define BORON	4	/* I prob'ly missed this one */

	#define NELEMENTS	5

	struct x index[NELEMENTS];

	y = index[NOTHING].whatever;
	z = index[HELIUM].whatever;
	ip = &index[0];		/* or ip = index; */
	w = ip[i].whatever;
This does  e x a c t l y  what you wanted it to do, and has the
advantage that your treatment of everything is uniform.  This
may (in the long run) show you ways to improve & streamline your
code.  [Flame deterrant:  improve & streamline are obviously not
the same, of course.]
-- 

	Joe Yao		hadron!jsdy@seismo.{CSS.GOV,ARPA,UUCP}

mikes@3comvax.UUCP (Mike Shannon) (11/07/85)

Paul Schauble in the cited article writes:
> Could people please comment on the portability of this structure?  If
> it's not, why not and how does one set up a structure where one needs to
> access the items both by pointer/subscript in a loop and by individual
> name in inline code?
> 
>     struct x {something};
>     struct x *ip;
> 
>     struct
>       {
>           struct x a;
>           struct x b;
>           struct x c;
>           struct x d;
>           struct x e;
>       }
>           index;
> 
>     y = index.a.whatever;
>     z = index.c.whatever;
> 
>     ip = (struct x *)&index;
>     ...
>     w = ip[i].whatever;

	Are you trying to drive us crazy?  Why the !@*? would you ever want
to give something two names??? Isn't life tough enough without this madness??
	I'd bet that your basic problem is something like this:

You have an array of seven structures, one for each day of the week.
You often process these structures as an array, but sometimes, you
want to just deal with one of them.  And you'd like clear, mnemonic names
to add the reader of your code.
	So, how about this:
#define MONDAY 0
#define TUESDAY 1
...
#define SUNDAY 6
struct x a[SUNDAY + 1];

	then you can do:
	for(i = Monday; i <= Sunday; i++) {
		a[i].whatever = something;
	}
	but you can also say:
	a[MONDAY].whatever = something;

	Thus it's readable, but you only have one name for a variable.
-- 
			Michael Shannon {ihnp4,hplabs}!oliveb!3comvax!mikes

mike@whuxl.UUCP (BALDWIN) (11/09/85)

> ...
> You have an array of seven structures, one for each day of the week.
> You often process these structures as an array, but sometimes, you
> want to just deal with one of them.  And you'd like clear, mnemonic names
> to add the reader of your code.
> 	So, how about this:
> #define MONDAY 0
> #define TUESDAY 1
> ...
> #define SUNDAY 6
> struct x a[SUNDAY + 1];
> 
> 	then you can do:
> 	for(i = Monday; i <= Sunday; i++) {
> 		a[i].whatever = something;
> 	}
> 	but you can also say:
> 	a[MONDAY].whatever = something;

This is where enums could actually be useful:

typedef enum {
	MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY,
	MAXDAY
} day_t;

struct x a[MAXDAY];
day_t d;

	for (d = 0; d < MAXDAY; d++)
		a[d].whatever = something

Now you don't have to give numbers to the days, or know what the names
of the first or last days are, and with MAXDAY, you can declare arrays
and loop over the values.  One slight problem, though.  This code gives
warnings from cc.  <, ++, and [] are all frowned upon if used with enums
(but the array declaration slips by...).  I consider this a massive mistake
in the implementation of enums, making them virtually useless.  You can't
even loop over them!  Anyway, ANSI C fixes this; enums are treated just
like any other integers.
-- 
						Michael Baldwin
						{at&t}!whuxl!mike

mikes@3comvax.UUCP (Mike Shannon) (11/12/85)

	Michael Baldwin in the cited article mentions that you can't
use an enumerated variable in expressions like
enumvar++
or
array[enumvar].

	I've noticed this too, and I wonder if there is any good reason
for restricting this use of enumerated types?  Or is it just a limitation
of the existing implementations? (which implies: "There are lots of compilers
out there which do not support this feature, therefore it can never
become part of the language.")
	If there is a good reason for disallowing this use of enumerated
variables, I'd like to hear it.
	Finally, if there is no good reason, can we expect this limitation
to be removed in the future?
-- 
			Michael Shannon {ihnp4,hplabs}!oliveb!3comvax!mikes

franka@mmintl.UUCP (Frank Adams) (11/15/85)

In article <274@3comvax.UUCP> mikes@3comvax.UUCP (Mike Shannon) writes:
>	So, how about this:
>#define MONDAY 0
>#define TUESDAY 1
>...
>#define SUNDAY 6
>struct x a[SUNDAY + 1];

Please, add another line:

#define NUM_DAYS 7

and make your declaration

struct x a[NUM_DAYS];

Otherwise, you're absolutely right.

Frank Adams                           ihpn4!philabs!pwa-b!mmintl!franka
Multimate International    52 Oakland Ave North    E. Hartford, CT 06108

jon@cit-vax.arpa (Jonathan P. Leech) (11/23/85)

    If I declare structures containing only one  data  type  (doubles)
	like this:

    struct a {
	double pt[3],
	       color[3];
    };

    struct b {
	double pt[3],
	       color[3],
	       normal[3];
    };

    is it safe	to  assume  that  they	are  equivalent  in  terms  of
	alignment and size to arrays of equivalent contents, i.e.

    double a_dummy[6],
	   b_dummy[9];

    Harbison & Steele makes me believe this, but  I'd  appreciate  any
	reliable information to the contrary. This question arises  in
	the context of a routine which needs to operate on  structures
	containing different amounts of  information  above  a	common
	base (polygon vertex location).

    Thanks,
    Jon Leech (jon@cit-vax.arpa)
    __@/

jsdy@hadron.UUCP (Joseph S. D. Yao) (11/27/85)

In article <3509@brl-tgr.ARPA> jon@cit-vax.arpa (Jonathan P. Leech) writes:
>    If I declare structures containing only one  data  type  (doubles)
>	like this:
>    struct a { double pt[3], color[3]; };
>    struct b { double pt[3], color[3], normal[3]; };
>    is it safe	to  assume  that  they	are  equivalent  in  terms  of
>	alignment and size to arrays of equivalent contents, i.e.
>    double a_dummy[6], b_dummy[9];

In a word, no.  Packing of data types is not defined between elements
of a structure.  It happens to work that way on almost every system
architecture I can think of; but let's posit something silly, like
a 24-bit word alignment with 36-bit doubles and 12-bit byte addressing.
Then words are at 0,2,4,6 bytes; doubles may fold in at 0,3,6,9
bytes; your first struct would have doubles at 0,3,6,10[alignment!],
13,16 bytes instead of 0,3,6,9,12,15 bytes as in the array.
-- 

	Joe Yao		hadron!jsdy@seismo.{CSS.GOV,ARPA,UUCP}