Initial values of File scoped and Block level variables

C

Chris Torek

For uninitialized global variables, the loader(LD) allocates data segment
memory using calloc() which does the "initialization" to NULL for all
elements ...

This is not in fact how it is implemented on Unix-like systems with
an "ld" linker or equivalent (gld). There is no call to calloc()
involved. The symbols are simply managed in a table until it is
time to assign locations to them; if they are still marked "bss"
at that point, they typically go into a "bss segment" (whose details
are file-format dependent -- a.out, COFF, and ELF are all at least
slightly different here; and some COFF and ELF formats also offer
a "small data segment" area into which small variables are collected
for register-offset addressing in the runtime image).

All of these details are irrelevant to portable C programs, which
need only concern themselves with the fact that static-duration
objects are initialized, as if by an explicit "= { 0 }". (Note
that braces are allowed for scalars; 0 suffices to set a double to
0.0 or a pointer to NULL; and only the first element of any aggregate
need be initialized to cause the rest to be initialized. Hence,
regardless of the object type to which the letter T is mapped, the
line:

T var = { 0 };

is always valid in C. If T is a function type, any initialization
is invalid, of course.)
So ...

struct {
int ii;
long ll;
char a[32];
} gvar;

creates an entry in the disk program image that the compiler emits to disk
that informs the loader to allocate 1 element of sizeof(gvar) memory.

In general, "gvar" in this case will be in a bss segment, along
with all other bss variables. When you actually run the binary,
the OS does not allocate one small chunk of memory at a time.
Instead, one or more entire pages or segments are allocated (or
marked for zero-fill, on a paging OS) based on the *total* size
given in the bss segment. This is quite OS-dependent, of course,
and assumes that the machine's all-bits-zero is the correct way
to initialize "double"s and pointers and so on.
Memory "allocated" between braces "{}" is actually stack memory
which retains the data from the last function to use that stack
memory. This memory can/will change from call to call being
altered by the "other" functions that are called in between.

It took me quite a while to figure out what you meant by this. As
stated, this is wrong, because it claims that, in:

void f(void) {
static int x;
...
}

x will be "stack memory". In fact, x is yet another "bss segment"
(or, potentially, small-data-segment) variable. The critical thing
is not the braces, but the fact that x has static storage duration.
If x had automatic storage duration -- which is indeed the default
for block-scope variables -- it would, as you say, typically be
stored on a (usually single, often OS-provided) stack.

Note however that IBM S/370 C compilers allocate "stack frames"
using the same, general-purpose "heap" memory that malloc() and
company use. The system does not provide, nor use, a stack: it
simply builds a LIFO data structure that *acts as* a stack (but is
not a single contiguous area, unlike typical OS-provided stacks).
(The S/370 approach has some big advantages when dealing with
languages that use coroutines.)
 
C

Chuck F.

Joseph said:
Keith said:
.... wholesome snip ...

NULL is a macro that expands to a null pointer constant; it
doesn't apply to non-pointer types.

NULL is "#define NULL 0" in every c compiler I have used, and I
code regularly on ten different *nix operating systems. NULL,
the macro, is neither a "pointer," int, long, or char, but can
be assigned to all.
In the above, ii will be set to (int)1, with ll and a[] set
to NULL.

No, ll will be set to 0L, and each element of a will be set to
'\0' (more generally, to zero converted to the appropriate
type).

You say potato, I say NULL -- most c developers think zero when
reading NULL.

And sooner or later you will run into "#define NULL (void*)0".

I am beginning to suspect Dionne IS a troll. Otherwise it is hard
to explain the combination of knowledge, ignorance, freetime, and
intractability he has shown.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
 
K

Keith Thompson

Chuck F. said:
Joseph Dionne wrote: [...]
You say potato, I say NULL -- most c developers think zero when
reading NULL.

And sooner or later you will run into "#define NULL (void*)0".

Well, <LIE>I hate to quibble</LIE>, but that's not a legal definition
for NULL. C99 7.1.2p5:

Any definition of an object-like macro described in this clause
shall expand to code that is fully protected by parentheses where
necessary, so that it groups in an arbitrary expression as if it
were a single identifier.

Consider "sizeof NULL".

"#define NULL ((void*)0)" is legal (if we assume that the standard's
lack of a guarantee that a parenthesized null pointer constant is also
a null pointer constant is merely an oversight).
I am beginning to suspect Dionne IS a troll. Otherwise it is hard to
explain the combination of knowledge, ignorance, freetime, and
intractability he has shown.

I have the same suspicion; he exhibits a rare combination of wrongness
and certainty.
 
R

Richard Heathfield

Keith Thompson said:
I have the same suspicion; he exhibits a rare combination of wrongness
and certainty.

What are you talking about? There's nothing rare about that combination.
 
K

Kenny McCormack

Chuck F. said:
I am beginning to suspect Dionne IS a troll. Otherwise it is hard
to explain the combination of knowledge, ignorance, freetime, and
intractability he has shown.

Indeed. He was inducted into the Loyal Order of Trolls, just last night.
Got the secret handshake, and everything.
 
D

Dave Thompson

Madhav said:

I don't know why statics and file scope objects get a default
initialisation. I know why automatics don't. It's a programmer choice. If
the programmer wishes the program to spend time assigning 0-values to
automatic objects, the programmer can choose that behaviour by writing:

int i = 0;

and if he doesn't wish that, he can simply write:

int i;
There is indeed a somewhat useful choice, but I'm pretty sure that's
not the reason. I'm pretty sure the reason is that automatics are
<caveat> on real machines and systems, though not formally required by
the standard </> allocated on some kind of stack and it costs
instructions and cycles to initialize them, whereas on many systems,
importantly including Unix for and along with which C was designed
(for somewhat limited values of designed) and implemented, statics are
initialized by the program-startup mechanism basically 'for free'.

Since systems provided this feature, program(mer)s used it, and when
the time came to standardize, that code had to be protected. It would
be a tad easier to remember, and explain, if consistent, but it's not.

- David.Thompson1 at worldnet.att.net
 
D

Dave Thompson

C is considered a 3rd generation, however IMHO it is more like a 2.5
generation language because reserved words of c translate one to one to
assembler instructions, with few exceptions.
While I for one concur that C is at or near the "low-level" end of
3GL, without trying to actually estimate it numerically (2.4? 2.6?):

If you actually meant this, you are the one being flippant. First,
taken literally, almost all C expressions (and expression-statements)
and many initialized declarations (using typedefed types) contain no
reserved words and yet generate code. Even assuming that you meant, as
people saying this usually do, 'primitive' language elements like the
computational operators, 'if', 'while', etc. it's not true for most or
all struct operations on most machines, operations on some (primitive)
datatypes on some machines, 'for' on almost all machines, etc., etc.

It was maybe as much as half true for early K&R1 C on (then-common)
CISC or medium-ISC machines like the PDP-11. (MISC is already used for
Minimal, and Intermediate Instruction Set Computer just looks ugly.)


- David.Thompson1 at worldnet.att.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,172
Messages
2,570,934
Members
47,478
Latest member
ReginaldVi

Latest Threads

Top