[comp.lang.c] static versus auto initialization

devine@cookie.dec.com (Bob Devine) (01/19/89)

  Would someone explain to me why the discrepancy between the
uninitialized elements of static and auto arrays?  Someone in
our group asked me a question on this point and the best answer
that I could generate was, in essence, "Cuz D.R. did it for speed".

  The problem looks like this:

        static char abc_static [5] = { 'a', 'b', 'c' };

        main()
        {
            auto char abc_auto [5] = { 'a', 'b', 'c' };
            . . .
        }

  For `abc_static', elements [3] and [4] are guarenteed to be zeroed 
out.  However, for `abc_auto', the same elements are garbage.  

  You can probably see that he initially had the static version and
was relying upon the zeros, so when he moved the array inside a
function he got burned...

Bob Devine

gwyn@smoke.BRL.MIL (Doug Gwyn ) (01/19/89)

In article <8901182125.AA06523@decwrl.dec.com> devine@cookie.dec.com (Bob Devine) writes:
>  For `abc_static', elements [3] and [4] are guarenteed to be zeroed 
>out.  However, for `abc_auto', the same elements are garbage.  

Most C compilers don't support auto aggregate initialization at all.
Whoever added it to your compiler apparently botched it.

rkl1@hound.UUCP (K.LAUX) (01/20/89)

In article <8901182125.AA06523@decwrl.dec.com>, devine@cookie.dec.com (Bob Devine) writes:
) 
)   Would someone explain to me why the discrepancy between the
) uninitialized elements of static and auto arrays?
) 
)   The problem looks like this:
) 
)         static char abc_static [5] = { 'a', 'b', 'c' };
) 
)         main()
)         {
)             auto char abc_auto [5] = { 'a', 'b', 'c' };
)             . . .
)         }
) 
)   For `abc_static', elements [3] and [4] are guarenteed to be zeroed 
) out.  However, for `abc_auto', the same elements are garbage.  
) 

	Correct.  (What more do you need? :-) ). 

	Unless you want to know that the Static has all elements initialized
at Compile Time and for Auto there is actual code to only initialize the
specified elements, the rest defaulting to whatever was in the memory
allocated for the array.

--rkl

evil@arcturus.UUCP (Wade Guthrie) (01/20/89)

>         main {
>             auto char abc_auto [5] = { 'a', 'b', 'c' };
>         }

Am I missing something, or is it illegal to initialize automatic
arrays?  It used to be under K&R C.


Wade Guthrie
evil@arcturus.UUCP
Rockwell International
Anaheim, CA

(Rockwell doesn't necessarily believe / stand by what I'm saying; how could
they when *I* don't even know what I'm talking about???)

guy@auspex.UUCP (Guy Harris) (01/20/89)

>  Would someone explain to me why the discrepancy between the
>uninitialized elements of static and auto arrays?  Someone in
>our group asked me a question on this point and the best answer
>that I could generate was, in essence, "Cuz D.R. did it for speed".

If "D.R." stands for Dennis Ritchie, I don't think he ever specified or
implemented initialization of automatic aggregates, period.  I know PCC
doesn't implement it as it comes out of the box.  K&R Second Edition
says:

	The first edition did not countenance initialization of
	automatic structures, unions, or arrays.  The ANSI standard
	allows it, but only by constant constructions unless the
	initializer can be expressed by a simple expression.

I guess the latter part means you can do

	struct foo {
		int	a;
		int	b;
	};

	static const struct foo foobar = { 666, 666 };

	void
	func(void)
	{
		struct foo bletch = foobar;

		...
	}

The May 13, 1988 draft specifically says that you can initialize
automatic structures and unions with a non-constant simple expression,
but doesn't mention arrays, which makes sense since you can't do array
assignment.

Presumably, the compiler in your example is one that implements
initialization of automatic aggregates:

>        static char abc_static [5] = { 'a', 'b', 'c' };
>
>        main()
>        {
>            auto char abc_auto [5] = { 'a', 'b', 'c' };
>            . . .
>        }
>
>  For `abc_static', elements [3] and [4] are guarenteed to be zeroed 
>out.  However, for `abc_auto', the same elements are garbage.

I consider this bogus.  The May 13, 1988 dpANS seems to agree:

	   If there are fewer initializers in a list than there are
	members of an aggregate, the remainder of the aggregate shall be
	initialized implicitly the same as objects that have static
	storage duration.

with no qualifiers indicating that this applies only to static
aggregates.  If your compiler purports to conform to some draft of the C
standard, it's not the May 13, 1988 draft....

john@chinet.chi.il.us (John Mundt) (01/20/89)

In article <8901182125.AA06523@decwrl.dec.com> devine@cookie.dec.com (Bob Devine) writes:
>
>  Would someone explain to me why the discrepancy between the
>uninitialized elements of static and auto arrays?  Someone in
>our group asked me a question on this point and the best answer
>that I could generate was, in essence, "Cuz D.R. did it for speed".
>
>  The problem looks like this:
>
>        static char abc_static [5] = { 'a', 'b', 'c' };
>        main()
>        {
>            auto char abc_auto [5] = { 'a', 'b', 'c' };
>            . . .
>        }

When the compiler creates the executable program, there is a special
area created for static and global variables.  The address is fixed
at compile time and will only hold abc_static values.  The "static"
is not really necessary here.  "static" here does not make it static
since it is already static by virtue of being global.  Instead, the
"static" notation serves to make it global to the file it is in.  
Thus, if you had a program made up of main.c, part2.c, and part3.c,
and this were in main.c, only functions in main.c could address and
use abc_static.

When abc_auto is created, it is created on the fly and on the stack
when main() is run.  It's address is computed as the address of the
base off the stack plus an offset to each member of abc_auto.
Since the stack is constantly reused and not initialized, the value 
of abc_auto[4] is whatever happened to be in that memory location.  
A static variable will run faster if it is addressed scads of times
since its final address does not have to be computed each time it
is accessed.  



-- 
---------------------
John Mundt   Teachers' Aide, Inc.  P.O. Box 1666  Highland Park, IL
john@chinet.chi.il.us
(312) 998-5007 (Day voice) || -432-8860 (Answer Mach) && -432-5386 Modem  

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

[Automatic aggregate initialisation is not allowed in `old C'.]

In article <7483@chinet.chi.il.us> john@chinet.chi.il.us (John Mundt) writes:
>A static variable will run faster if it is addressed scads of times
>since its final address does not have to be computed each time it
>is accessed.  

This is a curious statement.  Variables do not run at all.  I suspect
you mean `code that computes a variable's address will run faster if
the variable is static'; that statement is testable, and is false on
perhaps as many machines as it is true on others.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

gwyn@smoke.BRL.MIL (Doug Gwyn ) (01/20/89)

In article <7483@chinet.chi.il.us> john@chinet.chi.il.us (John Mundt) writes:
>Since the stack is constantly reused and not initialized, the value 
>of abc_auto[4] is whatever happened to be in that memory location.  

I'm sure that's what was happening, but it's not what is supposed to
happen.  Initialization of an array should initialize ALL its elements,
not just the ones explicitly specified in the source code.

guy@auspex.UUCP (Guy Harris) (01/21/89)

 >... for Auto there is actual code to only initialize the specified
 >elements, the rest defaulting to whatever was in the memory
 >allocated for the array.

Which, of course, won't be true on any ANSI C-conformant compiler
(barring a big surprise like the sections of the dpANS I cited in an
earlier posting changing) - the pANS says the implementation has to
initialize the unspecified elements the same way it would have
initialized them had they been static.

devine@cookie.dec.com (Bob Devine) (01/24/89)

My orignal posting said:
#  The problem looks like this:
# 
#         static char abc_static [5] = { 'a', 'b', 'c' };
#         main()
#         {
#             auto char abc_auto [5] = { 'a', 'b', 'c' };
#             . . .
# 
# For `abc_static', elements [3] and [4] are guarenteed to be zeroed 
# out.  However, for `abc_auto', the same elements are garbage.  

Doug Gwyn wrote:
> Most C compilers don't support auto aggregate initialization at all.
> Whoever added it to your compiler apparently botched it.

  I should have been clear that I was only talking about ANSI C.
As for botching, well, it's not clear.  See below.
 
Guy Harris wrote: 
> The May 13, 1988 dpANS says:
>  
> 	   If there are fewer initializers in a list than there are
>	members of an aggregate, the remainder of the aggregate shall be
> 	initialized implicitly the same as objects that have static
> 	storage duration.
> 
> with no qualifiers indicating that this applies only to static
> aggregates.  If your compiler purports to conform to some draft of the C
> standard, it's not the May 13, 1988 draft....

 The referenced section (implicit init of static duration objects) in
section 3.5.7 says that an implicit init using 0 is performed.  And since
aggregate types are just arrays and structures, that should be clear.

BUT then that is contradicted by K&R 2nd ed (page 86):

    "If there are fewer initializers for an array than the
    specified size, the others will be zero for external or
    static variables, but garbage for automatics."

  So, this is at least an error in one of the bibles.  Was the
auto-duration-object init section just added in the May 88 version?
(The lack of change bars on that section proves not.)  Was edition
of K&R was written using the Jan. 88 or previous dpANS document?
In general, the past behavior of auto-duration variables is maintained.
The May 88 version notes that any un-initialized auto variables
have "indeterminate" value.

Bob Devine

bph@buengc.BU.EDU (Blair P. Houghton) (01/24/89)

In article <876@auspex.UUCP> guy@auspex.UUCP (Guy Harris) writes:
>
> >... for Auto there is actual code to only initialize the specified
> >elements, the rest defaulting to whatever was in the memory
> >allocated for the array.
>
>Which, of course, won't be true on any ANSI C-conformant compiler
>[...] the pANS says the implementation has to
>initialize the unspecified elements the same way it would have
>initialized them had they been static.

Is that not going to add an aeon or two to the running time of some of
the more structured (read:  function-laden) programs?

				--Blair
				  "Well...I _could_ use the extra
				   time for lunch..."

dmr@alice.UUCP (01/24/89)

Bob Devine (in decwrl.8901231945.AA05683) points out that K&R 2ed
claims (p. 86) that partially initialized automatic aggregates
leave the part not explicitly initialized as garbage.

This claim is in error; as several people have pointed out, the pANS
guarantees that if an automatic is initialized at all, it is
initialized the same way as a static, with assignment of 0 to
the missing members.

			Apologies,
			Dennis Ritchie

guy@auspex.UUCP (Guy Harris) (01/25/89)

 >>[...] the pANS says the implementation has to
 >>initialize the unspecified elements the same way it would have
 >>initialized them had they been static.
 >
 >Is that not going to add an aeon or two to the running time of some of
 >the more structured (read:  function-laden) programs?

Only if they initialize automatic aggregates.  Since PCC doesn't allow
initialization of automatic aggregates, most of the programs out there
probably don't initialize them....

gwyn@smoke.BRL.MIL (Doug Gwyn ) (01/25/89)

In article <8826@alice.UUCP> dmr@alice.UUCP writes:
>This claim is in error; ...

At least programmers who believe it won't get into trouble
(but implementors will!).