[comp.lang.c] struct ? why

dan@hrc.UUCP (Dan Troxel VP) (10/11/88)

Could some of you please give reasons why 'struct'ing variables should be used
in 'C' programming? What speed increases are noticed if any? Code size at end
of compile smaller or larger? Things like that. I am making major changes to
some code for my company, and wish to increase the efficiency and readability
of the code.
-- 
Dan Troxel VP of Computer Operations @ 
Handwriting Research Corporation - 2821 E. Camelback Road Suite 600
Phoenix, AZ  85016       WK 1-602-957-8870        HM 1-602-435-1240
UUCP : asuvax!hrc!dan

eric@snark.UUCP (Eric S. Raymond) (10/14/88)

(Apologies to C gurus who find this too elementary. But if there's one guy
like this reading the list, there are probably others too intimidated by
the abstruse tone of our usual stuff to post. Let's be nice to novices --
as they are, so once were we...)

In article <315@hrc.uucp>, dan@hrc.UUCP (Dan Troxel VP) writes:
>Could some of you please give reasons why 'struct'ing variables should be used
>in 'C' programming? What speed increases are noticed if any? Code size at end
>of compile smaller or larger? Things like that.

Structs are provided not for efficiency's sake but in order to permit you to
logically group together data that the program will use together. The classic
example is employee records in a personnel database. Instead of declaring
separate arrays, as in:

	char	name[MAXEMPLOYEES][MAXNAME];	/* employee names */
	int	salary[MAXEMPLOYEES];		/* salaries */

it leads to more readable code to write

	struct employee
	{
		char	name[MAXNAME];	/* employee names */
		int	salary;		/* salaries */
	};

	struct employee people[MAXEMPLOYEES];

and then refer to people[n].name or people[n].salary. This helps you keep
the data organization you're using in mind.

>                                                 I am making major changes to
>some code for my company, and wish to increase the efficiency and readability
>of the code.

Please don't take this as a flame or insult -- but if you don't already 
understand program design well enough to see why structs are useful, you'd
almost certainly be better off farming the job out to someone who does.
-- 
      Eric S. Raymond                     (the mad mastermind of TMN-Netnews)
      UUCP: ...!{uunet,att,rutgers}!snark!eric = eric@snark.UUCP
      Post: 22 S. Warren Avenue, Malvern, PA 19355      Phone: (215)-296-5718

albaugh@dms.UUCP (Mike Albaugh) (10/18/88)

From article <e7VX3#2ntZhS=eric@snark.UUCP>, by eric@snark.UUCP (Eric S. Raymond):
> (Apologies to C gurus who find this too elementary. But if there's one guy
> like this reading the list, there are probably others too intimidated by
> the abstruse tone of our usual stuff to post. Let's be nice to novices --
> as they are, so once were we...)
	Yes, lets.
> 
> In article <315@hrc.uucp>, dan@hrc.UUCP (Dan Troxel VP) writes:
>>Could some of you please give reasons why 'struct'ing variables should be used
>>in 'C' programming? What speed increases are noticed if any? Code size at end
>>of compile smaller or larger? Things like that.

[ tutorial on why one _should_ use structs deleted]

	Maybe dan@hrc has heard someone talking about another practice,
becoming more common lately, of grouping only vaguely related variables
into exactly one instance of a struct. This actually decreases program
clarity, but can be a fairly big win on machines like the 68K, which
have a fast (well, faster) way to access things that are some (small)
offset from a register based pointer. I'm not proud of it, but I have
used such hacks where speed/code size was paramount and I was forbidden
to use Assembly (or the linker wouldn't co-operate any other way). I
repeat that I can't recommend it when you don't need it, but it can
be a big win on "efficiency". I said essentially this in a mail message
which bounced.

| Mike Albaugh (albaugh@dms.UUCP || {...decwrl!turtlevax!}weitek!dms!albaugh)
| Atari Games Corp (Arcade Games, no relation to the makers of the ST)
| 675 Sycamore Dr. Milpitas, CA 95035		voice: (408)434-1709
| The opinions expressed are my own (Boy, are they ever)

lazer@mnetor.UUCP (Lazer Danzinger) (10/18/88)

Eric S. Raymond writes:
>
>In article <315@hrc.uucp>, dan@hrc.UUCP (Dan Troxel VP) writes:
>>Could some of you please give reasons why 'struct'ing variables should be used
>>in 'C' programming? What speed increases are noticed if any? Code size at end
>>of compile smaller or larger? Things like that.
>
>Structs are provided not for efficiency's sake but in order to permit you to
>logically group together data that the program will use together. 
>
>it leads to more readable code . . .
>
    While I concur that the proper usage of structures leads to more
    readable code, there may indeed be an efficiency related aspect to
    its usage as well (in certain applications) which should not be 
    overlooked.

    Consider the following two functions:

bool update_employee_rec(name, address, salary, id_no, height, weight, etc)
char	*name;
char	*address;
float	*salary;
int	*id_no;
float	*height;
float	*weight;
.
.
.

bool update_employee_rec(employee_rec)
Employee *employee_rec;

    In the former format, the compiler will have to generate code to
    push many variable addresses on the stack (each time the function 
    appears in the code).

    In the latter format, the compiler has to generate code to push
    a single address on the stack (the address of the structure).
    (This results in a smaller object and executable size.)

    Naturally, at run-time, a function coded in the latter format 
    will run (much) faster as well, since there is a minimum of pushing
    and popping off the stack. 

    Of course the measure of efficiency obtained depends on the number
    of times a function is invoked, and how many parameters the function
    would otherwise have.

    One should be careful against the abuse of stuctures, though.
    I have frequently seen code where a pointer to a structure is passed 
    to a function, but only 2 or 3 members of the structure are
    referenced in the function, out of the _many_ members belonging to 
    the structure. This is definitely poor programming. It obscures
    the interface, and makes the code more difficult to re-use.
    Another similar danger is the temptation to throw just about everything,
    short of the kitchen-sink, into a single structure. Why do some
    programmers do this? 
    So that they can pass a single parameter in the functions that 
    they write, of course! 

-- 
-----------------------------------------------------------------------------
Lazer Danzinger      | "Ben Zoma said, 'Who is wise?  One who learns from 
lazer@mnetor         | every  person...Who is courageous?  One who conquers 
                     | his [evil] inclination...Who is wealthy?  One who is 
                     | satisfied with his portion...Who is respected?  One who 
(416) 475-8980       |  respects his fellow man...'"         -- Avot 4:1
----------------------------------------------------------------------------

blm@cxsea.UUCP (Brian Matthews) (10/19/88)

Lazer Danzinger (lazer@mnetor.UUCP) writes:
|Eric S. Raymond writes:
|>In article <315@hrc.uucp>, dan@hrc.UUCP (Dan Troxel VP) writes:
|>>Could some of you please give reasons why 'struct'ing variables should be used
|>>in 'C' programming? What speed increases are noticed if any? Code size at end
|>>of compile smaller or larger? Things like that.
|>Structs are provided not for efficiency's sake but in order to permit you to
|>logically group together data that the program will use together. 
|>it leads to more readable code . . .
|    While I concur that the proper usage of structures leads to more
|    readable code, there may indeed be an efficiency related aspect to
|    its usage as well (in certain applications) which should not be 
|    overlooked.
|    Consider the following two functions:
|bool update_employee_rec(name, address, salary, id_no, height, weight, etc)
|char	*name;
|char	*address;
|float	*salary;
|int	*id_no;
|float	*height;
|float	*weight;
|bool update_employee_rec(employee_rec)
|Employee *employee_rec;

Two problems:

1.  The functions aren't equivalent.  Someone calling the first one knows
that name, address, etc.  can't be modified by update_employee_rec, as it
gets its own copy of everything.  Someone calling the second function has
no such guarantee.  This difference may be more important than any
minimal performance improvement gained.

2.  While CALLING the second function may be faster, accessing name and
address and such in it may be slower.  Accessing name in the first
function (on your run-of-the-mill CISC processor) will be something like

	move	offset(frame pointer), somewhere

In the second function, it's

	move	offset(frame pointer), temp addr reg
	move	offset(temp addr reg), somewhere

This will be ameliorated somewhat by placing employee_rec in a register
(assuming you have enough registers available, etc.), but a good compiler
won't stack and unstack all of the arguments for the first function
either, so you can't immediately assume that using the second function
will result in a performance improvement.

-- 
Brian L. Matthews  blm@cxsea.UUCP   ...{mnetor,uw-beaver!ssc-vax}!cxsea!blm
+1 206 251 6811    Computer X Inc. - a division of Motorola New Enterprises