Re: Storage of Variables



The Natural Philosopher wrote:
Jean-David Beyer wrote:
Grant Edwards wrote:
On 2008-08-16, Jean-David Beyer <jeandavid8@xxxxxxxxxxx> wrote:
Grant Edwards wrote (in part):
On 2008-08-16, Jean-David Beyer <jeandavid8@xxxxxxxxxxx> wrote
(also in part):
Static variables were stored in RAM.
I was afraid that might be ambiguous. In the C compilers for the
AT&T 3B computers as well as the PDP-11 and VAX machines, there
were three memory "sections" called text, data, and bss. Text had
the program in it. Data had initialized data in it. Bss was static
data that had not been initialized; this contained undefined values
-- in practice, they put in trap instructions so if you tried to
execute them, you got interrupted. Other implementations put NAN in
there, and yet others filled it with zeros.
The C language definition requires them to be zeros.
I do not believe this is correct. Certainly, the contents of register
variables are undefined unless something is explicitly assigned to
them. (And in some optimizing compilers, register statements are
ignored and the registers are overloaded (different things are assigned
to a register at different times).) Furthermore, I have never seen the
code at entry to a function zero out the stack. In correct code, this
would never be necessary, and in incorrect code you are seriously
asking for trouble.

malloc and local variables are undefined, static and global variables are
always zero.

I think the original part of this thread concerned the values of _automatic_
variables. In C, there is really no such concept as a heap, though you could
consider the stuff returned by sbrk() and therefore by malloc() to be from a
heap. And in the case of automatic variables (always kept on a stack I would
think), the C Standard, Paragraph A8.7 Initialization has this to say:

"The inital value of an automatic [stack] object not explicitly initialized
is undefined."

This is done by the program loader or the compiler itself.

It would be very inefficient for the _compiler_ to do it, since to
initialize the storage, it would have to be in the data segment instead of
the bss segment. And to initialize the data segment, there would have to
be the e equivalent of an initial value for every object. It is simpler to
have the loader zero it all out if that was wanted. It would make the object
file much smaller that way too.

Our loader did initialize the bss segment with zeros, but that was to catch
some of the dereferences to uninitialized pointers. The OS was set to never
put the bottom page into the process's data space. Thus, when a pointer
pointed to 0 or thereabouts, you got a segmentation fault that helped you
debug your program. But that was not required by the C language. And of
course this did not work for all bad pointers (in particular, automatic ones).

All memory
associated with the heap is guaranteed to be zero, or as definied if
defined.

Maybe your implementation did that, but since in C the only way the heap is
accessed is by sbrk() and malloc(), and they return undefined values. If
your implementation decides to define them initially as zero, OK, but the
programmer better not rely on this because if this space is returned to the
heap, and then re-used, it will no longer be zero.

--
.~. Jean-David Beyer Registered Linux User 85642.
/V\ PGP-Key: 9A2FC99A Registered Machine 241939.
/( )\ Shrewsbury, New Jersey http://counter.li.org
^^-^^ 17:40:01 up 9 days, 23:46, 4 users, load average: 3.99, 4.01, 4.00
.



Relevant Pages