[comp.lang.c] When should variables within blocks be allocated?

brnstnd@stealth.acf.nyu.edu (01/19/90)

In article <253@usblues.UUCP> tom@usblues.UUCP (Tom Markson) writes:
> The .s file indicates that all stack space is allocated at the start of a 
> function.  

If a function contains the statement if(0) { int k[100000000]; ... },
should the space for k be allocated? Every compiler I've tried allocates
variables at function entry like Tom's, but it would be nice to save
100M of memory if k is never used. I can't find any ANSI rules on this.

If the answer is that the space for k can be ignored, are there any
compilers smart enough to optimize k away? Are there any compilers that
go all the way and allocate k the moment they enter the block? Is the
space saved worth the efficiency loss?

---Dan

henry@utzoo.uucp (Henry Spencer) (01/20/90)

In article <26449@stealth.acf.nyu.edu> brnstnd@stealth.acf.nyu.edu (Dan Bernstein) writes:
>If a function contains the statement if(0) { int k[100000000]; ... },
>should the space for k be allocated? Every compiler I've tried allocates
>variables at function entry like Tom's, but it would be nice to save
>100M of memory if k is never used. I can't find any ANSI rules on this.

It's covered by the as-if rule:  if it's never used, you can't tell whether
it was allocated or not, so the compiler is entitled to optimize it out.
See 2.1.2.3 for the formal statement of the as-if rule.

>If the answer is that the space for k can be ignored, are there any
>compilers smart enough to optimize k away? Are there any compilers that
>go all the way and allocate k the moment they enter the block? Is the
>space saved worth the efficiency loss?

Compilers that do smart register allocation have at least a fighting chance
of noticing that k is never used, although it being an array might complicate
things.  Most current compilers do all their allocation at function-entry
time:  it's usually more efficient and it simplifies stack-frame management.
-- 
1972: Saturn V #15 flight-ready|     Henry Spencer at U of Toronto Zoology
1990: birds nesting in engines | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

karl@haddock.ima.isc.com (Karl Heuer) (01/20/90)

In article <26449@stealth.acf.nyu.edu> brnstnd@stealth.acf.nyu.edu (Dan Bernstein) writes:
>If a function contains the statement if(0) { int k[100000000]; ... },
>should the space for k be allocated?  Every compiler I've tried allocates
>variables at function entry like Tom's, but it would be nice to save
>100M of memory if k is never used. I can't find any ANSI rules on this.

The critical rule here is known as the "as-if" rule: the Standard does not
(indeed, cannot) say anything about what sort of "machine code" is generated;
it describes the behavior of conforming programs.  The implementation must
behave *as if* certain things were true, but if there is no way for a correct
program to detect the difference, then it is free to optimize things away.  In
particular, unused variables need not be allocated.  Such compilers exist.

>Are there any compilers that go all the way and allocate k the moment they
>enter the block?  Is the space saved worth the efficiency loss?

I've seen compilers that do this, but I generally consider it a loss.

Karl W. Z. Heuer (karl@haddock.isc.com or ima!haddock!karl), The Walking Lint

mcdonald@aries.scs.uiuc.edu (Doug McDonald) (01/20/90)

In article <26449@stealth.acf.nyu.edu> brnstnd@stealth.acf.nyu.edu (Dan Bernstein) writes:
>If a function contains the statement if(0) { int k[100000000]; ... },
>should the space for k be allocated? Every compiler I've tried allocates
>variables at function entry like Tom's, but it would be nice to save
>100M of memory if k is never used. I can't find any ANSI rules on this.
>
I just tried it on the new compiler that arrived in the mail yesterday.

giving it the program

void sub() {
    while (0) {
        int j[1000000],i;
        for (i = 0; i < 1000000; i++) j[i] = i;
    }
} 


resulted in no data allocation and the generated code

ret

which is a pretty small function. MicroWay NDPC 2.00 for the 386.
Exchanging the while(0){ and int j[... lines gave the same result.

The VMS C compiler has been this good for quite a while.

Doug McDonald (mcdonald@aries.scs.uiuc.edu)

adrian@mti.mti.com (Adrian McCarthy) (01/23/90)

In article <15699@haddock.ima.isc.com> karl@haddock.ima.isc.com (Karl Heuer)
writes:

>[compilers are] free to optimize things away.  In
>particular, unused variables need not be allocated.  Such compilers exist.

So the relatively common practice of trying to get an identification string
into the object and executable files by declaring an otherwise unused
character string may be pointless.  For example, many programmers put a line
like:

  static char *RCSid = "$Header$";

into their code.  When they check it out from their configuration management
system (RCS in this example), $Header$ gets expanded to an identification
string.  Later, they expect a strings-type command to spit out the expansion
of the $Header$.  But if RCSid is never used anywhere else in the program,
some compilers might optimize it away.

A better solution would be to provide a switch/option/qualifier to the
program which simply outputs the string.  That would guarrantee RCSid is not
optimized out and it allows folks on systems without a strings-type command
to also get this information.

>Karl W. Z. Heuer (karl@haddock.isc.com or ima!haddock!karl), The Walking Lint

Aid.