Re: Statement on Schildt submitted to wikipedia today



On 2009-09-11, Francis Glassborow <francis.glassborow@xxxxxxxxxxxxxx> wrote:
You know that a great deal of this argument about needing a stack
resolves round what that word is meant to mean. Last in first out queues
can be implemented in many ways. The problem is that Schildt decided to
describe a very specific implementation and not one that is universely used.

Well, I got bored. So I decided to go track down my copy of C:TCR (3rd
Edition, copyright 1995). Page 426 starts Chapter 16, "Dynamic Allocation".

"Dynamic allocation is the second way that a program can acquire
storage for data. In this method, storage is allocated from free
memory as needed during the execution of the program. The region of
free memory that is used for dynamic allocation is called the heap.
Traditionally, the heap lies between your program and its permanent
storage area, and the stack. Figure 16-1 shows conceptually how a C
program would apapear in memory. (parenthetical elided) The stack
grows downward as it is used. [...] Memory to satisyfy a dynamic
allocation request is taken from the heap, starting just above the
global variables and growing towards the stack."

This isn't particularly accurate. It's also not didactically useful. This
explanation occurs fairly late in, along with a detailed discussion of the
near, far, and huge 80x86 memory models. While it's certainly true that
those models were, at the time, significant to many developers... It utterly
undermines the claim that, at the time when we are hearing about the stack,
Schildt is trying to use a "minimal" model to avoid complicating things;
the multiple non-overlapping memory models and pointer types are far, far,
more complicated than a real discussion of stacks, registers, and other ways
of handling automatic storage.

There is an earlier part, on page 13, which says:

A compiled C program creates and uses four logically distinct regions
of memory that serve distinct functions. The first region is the
memory that actually holds your program code. The next region is
memory where global variables are stored. The remaining two regions
are the stack and the heap. The stack is used for a great many things
while your program executes. It holds the return addresses of
function calls, arguments to functions, and local variables. It will
also save the current state of the CPU. The heap is a region of free
memory that your program can use via C's dynamic allocation functions
for linked lists and trees.

The exact layout of your program may vary from compiler and compiler
and environment to environment. For example, most C compilers for the
8086 family of processors have several different ways to organize
memory because of the segmented memory architecture of the 8086.
(The memory models of the 8086 family of processors are discussed
later in this book.)

Although the exact physical layout of each of the four regions of
memory differs among CPU types and C implementations, the diagram in
Figure 1-2 shows conceptually how your C programs appear in memory.

Figure 1-2 depicts a rectangle divided into four parts:

Stack
|
v
^
|
Heap


Global Variables

Program Code

The questions we must evaluate are:

1. Is this description correct?
2. Is it at least substantively correct?
3. Was it at least substantively correct for the time when it was written?
4. Was it didactically superior to other possible explanations?

That last is probably the key defense. No one seriously defends #1. #2 is a
more interesting debate. I don't know exactly how DOS-type compilers worked
back then, but on the systems I was familiar with, I do not believe it was
even substantively correct. On Amiga and Mac systems, which multitasked but
lacked a fully-functional VM system, it is just plain not even close; stack
and heap were both allocated in free memory, with multiple different programs
having stacks and heap spaces which might be interleaved with each other. You
could easily end up with the stack for one program between two chunks of the
heap of another program.

Also significantly, the comment about global variables is incorrect. It is
not global variables, but *static* variables, which generally had reserved
space -- and local static variables would not be in the stack, but would be
in the reserved space. Or spaces; many systems already distinguished between
blocks with specific initialized values and blocks of storage which could be
initialized to zero or required no initialization. There is no general
guarantee that variables will all be moved into a separate category, and even
if they were, the key is not "global" but "static" objects.

The real question, I guess, is the didactic benefit. Does this explanation
help prepare the user to understand the coming text?

No, it doesn't.

I'm waiting for something to compile. I might as well have a go at this.

The C language allows for the declaration of variables of various
types, called "objects". An object is simply a region of storage
(generally memory) which holds a value. Most objects are stored
in memory, and the location in memory where they are stored is called
an "address". While it exists, each object's address is unique
to that object. Generally, addresses correspond to some kind of
layout of memory, the details of which vary between implementations.

While some objects exist from the start to the end of program
execution, not all do. The storage used to hold an object has a
"storage duration", or lifetime, determining when the storage
is reserved, and when the storage is made available again to be
used for storing other objects. There are three storage durations
in the C language; static, automatic, and dynamic.

Objects with "static" storage duration have storage reserved before
your program begins execution, and retain that same storage for the
entire lifetime of your program. Global variables are the most common
example of objects with static storage duration.

Objects with "automatic" storage duration have storage reserved
when they are used (or possibly earlier), and the storage is released
sometime after they are no longer available. For instance, a local
variable in a function has automatic storage duration; it is available
when the block of code containing it is executing, but the space
it was in may be reused at some point after that code completes. The
exact rules may vary from one implementation to another, or depending
on compiler options; all you need to be aware of is that you cannot
continue to refer to an object with automatic storage duration after
the block containing the declaration has been exited, and that you
do not need to explicitly allocate or deallocate these objects.

Objects with "dynamic" storage allocation have storage reserved by
explicit actions, such as calls to special library functions. That
storage remains reserved until it is released by explicit actions.
You must take care to release the storage of dynamic objects when
you are done using them, and you cannot access the object after you
have released its storage.

I'm not sure that's right, but it's not awful for a first draft, I don't
think. That took twenty minutes or so. I'm guessing that it would be at
least as useful to a novice programmer as Schildt's explanation, and it
has the advantage that it is much less likely to cause the reader trouble
later; I don't know of any system failing to match this description, and
don't think one would be possible.

The above does not address VLA types, but then, they didn't exist in 1995. :)

I wonder why Schildt left the world of programming in order to write
books on the subject. Good programmers generally earn a great deal more
than technical authors, particularly the latter when they take the time
to make sure their work is technically correct as well as fluently written.

FWIW: I earned substantially more money per hour doing technical writing,
but it wasn't as stable. Books, not so much unless they're bestsellers,
but bespoke technical writing, by someone who knows the field, can be very
rewarding.

I believe that Schildt probably has a genuine passion for communication. It's
a shame he was not as devoted to learning as he was to teaching.

-s
--
Copyright 2009, all wrongs reversed. Peter Seebach / usenet-nospam@xxxxxxxxx
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
--
comp.lang.c.moderated - moderation address: clcm@xxxxxxxxxxxx -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
.



Relevant Pages

  • Re: REGION=0M and LSQA
    ... At the time, memory was very expensive, and we ... remaining storage and always issued a return code zero. ... programs actually worked in production, ... all of the resources used by the job up until that point ...
    (bit.listserv.ibm-main)
  • Re: storage locations for different data types
    ... and that's why it should be preferred to talk about storage ... or global / heap / stack). ... (Interestingly, temporary objects have automatic storage duration, but ... I remember extensive discussions about the name "heap". ...
    (comp.lang.cpp)
  • Re: What is the difference between the Heap and the Stack?
    ... lives in RAM (random-access memory), but has direct support from the ... the compiler doesn't need to know how much storage it needs to allocate ... > from the heap or how long that storage must stay on the heap. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: main memory vs. storage memory on 128 meg samsung 1 730 ppc phone
    ... This type is commonly used in WM devices (and storage cards). ... OS would copy itself to RAM taking out some of it. ... > How fast is the main memory compared to the flash ram memory in ... >> Fake storage card composed of flash is relatively slow, ...
    (microsoft.public.dotnet.framework.compactframework)
  • Off Topic: Stack vs. Heap
    ... Is there any difference in allocating on the heap versus the stack? ... > about allocating a lot of stuff on a garbage collected heap. ... > concept like this follow from the fact that heap storage is better to use ...
    (comp.lang.cpp)

Loading