[net.lang.c] Block Initialization

swang@calma.UUCP (10/08/86)

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

What is the most suitable (fast and portable among versions of Unix)
way to do block initialization?

Say I have a big structure of close to 4 Kbytes.
	
	typedef  struct {
		....
		....
	    } bigstruct;

	sizeof(bigstruct) == 4 +/- 10 Kbytes 

The details of this structure is too long, complicated and tedious to
duplicate here.  Its size may not be exactly 4Kb.

The chore is to initialize the entire structure to zero.  How do I do it?

One possible way is a function zero():

	main()
	{
		bigstruct p;
		zero((char *)&p);
	}
	zero(p)	char *p;	/* NOTE THE TYPE */
	{
		register int i = sizeof(bigstruct);
		while (i--) *p++ = 0;
	}

Another being a library call bzero()

	main()
	{
		bigstruct p;
		bzero(&p, sizeof(p));
	}

Is bzero() the optimum for this purpose for all Unix machines?
Is it portable, the Vax version is written in assembly?


I appreciate e-mailing opinions to me.

UUCP: ucbvax!calma!swang

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

gwyn@brl-smoke.ARPA (Doug Gwyn ) (10/10/86)

In article <586@calma.UUCP> swang@calma.UUCP (Sin-Yaw Wang) writes:
>Say I have a big structure of close to 4 Kbytes.
>	
>	typedef  struct {
>		....
>		....
>	    } bigstruct;
>
>The chore is to initialize the entire structure to zero.  How do I do it?

The wrong way is to use bzero(), which fills a region with 0 bytes
and which exists only on Berkeley-based systems (System V/X3J11 use
memset()).  There are at least two problems with this:
	(1)  the struct padding may not be accessible on some architectures,
		so storing into it may cause a trap;
	(2)  0 bytes are not necessarily appropriate representations of the
		value zero for all data types, especially floating-point.

Try the following:

static bigstruct zero;	/* required to be initialized to 0s of proper types */

...

	bigstruct p;

	p = zero;	/* struct copy is optimized by compiler */

pedz@bobkat.UUCP (Pedz Thing) (10/13/86)

In article <586@calma.UUCP> swang@calma.UUCP (Sin-Yaw Wang) writes:
>What is the most suitable (fast and portable among versions of Unix)
>way to do block initialization?
>

If you have an extra 4k of memory space I do the following:

----------
static struct bigstruct zerobigstruct;

main()
{
  struct bigstruct tobeused;

  tobeused = zerobigstruct;
  ...
}
----------

The above code obviously assumes that the compiler has structure
assignment which I think is a pretty safe assumption if you are
dealing with C compilers on Unix machines.

I realize that this is going to start the big debate about assignment
of structures being either field by field or a block move.  Lets not
get into that argument please.  My point here is if the compiler feels
a block move for the above code is correct then it can produce that.
If the compiler prefers field by field assignment, it can produce
that.  (I personally assume the above code produces a block move and
if that is not what I want, then I must explicitly tell the compiler
otherwise).
-- 
Perry Smith
ctvax ---\
megamax --- bobkat!pedz
pollux---/

chris@umcp-cs.UUCP (Chris Torek) (10/22/86)

>>The chore is to initialize the entire structure to zero.  How do I do it?

In article <4510@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn
(VLD/VMB) <gwyn>) writes:
>The wrong way is to use bzero(), which fills a region with 0 bytes
>....

Structure assignment is fine in most cases, but suppose instead that
some hapless programmer is supposed to initialise a 40K-byte structure
using a small model compiler on an IBM PC?  There is no space for a
second copy of the structure.  Using bzero() here (assuming it exists,
or after writing it) is reasonable, given the compiler limitations.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu

tps@sdchem.UUCP (Tom Stockfisch) (10/23/86)

In article <3965@umcp-cs.UUCP> chris@umcp-cs.UUCP (Chris Torek) writes:
>>>The chore is to initialize the entire structure to zero.  How do I do it?
>
>Structure assignment is fine in most cases, but suppose instead that
>some hapless programmer is supposed to initialise a 40K-byte structure
>using a small model compiler on an IBM PC?  There is no space for a
>second copy of the structure.  Using bzero() here (assuming it exists,
>or after writing it) is reasonable, given the compiler limitations.

The obvious solution is to make assignment of zero to any structure a
defined operation guaranteed to get the appropriate bit patterns into
all the pointer elements.  Much cleaner than

	struct big_sucker { ... }	zero;	/* initialized to all zeros */
	main()
	{
		struct big_sucker	var;
		...
		var =	zero;	/* clear all elements of var */
		...
	}

would be
		var =	0;	/* (no comment needed) */

and much better for portability than using bzero().
I hope this gets provided for in ANSI C.

-- Tom Stockfisch, UCSD Chemistry

chris@umcp-cs.UUCP (Chris Torek) (10/29/86)

In article <414@sdchema.sdchem.UUCP> tps@sdchemf.UUCP (Tom Stockfisch) writes:
>The obvious solution is to make assignment of zero to any structure a
>defined operation guaranteed to get the appropriate bit patterns into
>all the pointer elements. ...
>
>		struct big_sucker	var;
>
>		var =	0;	/* (no comment needed) */

I dislike this: it is Yet Another Special Case.  I think the proper
obvious solution is to allow aggregate structure constants:

		var = { 0 };

The compiler can (*internally*) recognise this as a special constant
and not generate a static data object.  Aggregate structure constants
have other nice features:

	f(x)
		struct foo x;
	{
		...
	}

		f((struct foo) { 1, 27.3, "Hello world" });

They have problems as well; witness the ugly syntax used to attach
a type to an otherwise typeless aggregate.  As with the nil pointer
constant `0', aggregate constants can pick up their types from
expression context, but there are always cases where the context
is missing.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu

tps@sdchem.UUCP (Tom Stockfisch) (10/30/86)

[ ">>" and "" is me (Tom Stockfisch), and ">" is Chris Torek ]

>>The obvious solution is to make assignment of zero to any structure a
>>defined operation guaranteed to get the appropriate bit patterns into
>>all the pointer elements. ...
>>
>>		struct big_sucker	var;
>>
>>		var =	0;	/* (no comment needed) */

>I dislike this: it is Yet Another Special Case.

I see this as *eliminating* a special case, since we already have

	double		x =	0;
	int		i =	0;
	long		j =	0;
	char		*p =	0;
	char		c =	0;
	struct foo	*bar =	0;

and (as a special case)
	
	struct foo	elt =	0;

is disallowed.  All this extension does (I think) is add one more conversion
rule, specifying how "0" gets widened to a "struct foo".
So what would be the harm?

>...I think the proper
>obvious solution is to allow aggregate structure constants:
>
>		var = { 0 };

Of course I would like this feature to be added as well, especially when I
have to deal with complex numbers.  If I had to choose, I would take
	
	var =	{ 0 };

since it is more powerful.

-- Tom Stockfisch, UCSD Chemistry