By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,695 Members | 1,358 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,695 IT Pros & Developers. It's quick & easy.

Initial values of File scoped and Block level variables

P: n/a
Hi all,

I did not understand why do the global vars are
initialized to NULL where as the block level variables have random
values? I know that the C standard requires this as was mentioned in a
recent thread.

I want to know why this descrimination is in place. Can't all the
variables be initialised to NULL automatically by the compiler? This
would make programming a little easier.

Regards,
Madhav.

Jan 6 '06 #1
Share this Question
Share on Google+
27 Replies


P: n/a
Madhav <ma***********@gmail.com> wrote:
I did not understand why do the global vars are
initialized to NULL where as the block level variables have random
values? I know that the C standard requires this as was mentioned in a
recent thread.

I want to know why this descrimination is in place. Can't all the
variables be initialised to NULL automatically by the compiler? This
would make programming a little easier.


No, the data for automatic variables can not be initialized to NULL by
the compiler.

Before main() is called, a system-specific piece of code runs, which
prepares the environment for your C program to run in. One of it's tasks
is to clear the .bss section, e.g. setting all global and static
variables to zero.

Automatic variables are allocated on the stack, and do not have a fixed
address. The same memory locations will often be re-used when entering
and leaving functions. To clean all automatic variables every time a
function or block is entered, your compiler would have to insert a piece
of code at the beginning of *every function* to do that.

--
:wq
^X^Cy^K^X^C^C^C^C
Jan 6 '06 #2

P: n/a
Madhav said:
Hi all,

I did not understand why do the global vars are
initialized to NULL where as the block level variables have random
values? I know that the C standard requires this as was mentioned in a
recent thread.
The Standard requires that all static and file scope objects that are not
explicitly initialised by the program are given default static initialiser
values, viz. 0, 0.0, NULL (recursively for aggregates).

The Standard makes no such demands for automatic objects, except in the case
of partial initialisation of aggregate objects (where the partial
initialisation is honoured, and the rest of the object initialised as
mentioned earlier).
I want to know why this descrimination is in place.
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;

which indicates that, at this stage, he isn't fussed about i's value.
Can't all the
variables be initialised to NULL automatically by the compiler?
Yes, a compiler is free to do that if it wishes (NULL for pointers, 0 for
integers, 0.0 for floating point numbers, and the obvious for structs,
unions, and arrays), but it is not /required/ to do that.
This would make programming a little easier.


I'm tempted to agree, but it would diminish programmer choice. I like my
objects to start off with known values, in the interests of determinism, so
your proposal would suit my style of programming. But other programmers
prefer it the way it is now, and whilst it is possible for me to get the
effect I want by taking the current strategy and adding code (typically as
simple as = {0} in my case), the reverse would not be true.

I am not (yet) so monumentally egomaniacal as to insist that every C
compiler writer in the world should change their product just to suit my
coding style. But I'm working on it.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jan 6 '06 #3

P: n/a
us****@zevv.nl said:
No, the data for automatic variables can not be initialized to NULL by
the compiler.
Not so. They could be. They just aren't.
Automatic variables are allocated on the stack, and do not have a fixed
address. The same memory locations will often be re-used when entering
and leaving functions. To clean all automatic variables every time a
function or block is entered, your compiler would have to insert a piece
of code at the beginning of *every function* to do that.


See? I told you it was possible!

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jan 6 '06 #4

P: n/a
Richard Heathfield <in*****@invalid.invalid> wrote:

[snip discussion about initialization of automatic variables]
I'm tempted to agree, but it would diminish programmer choice.


I don't want to be too broad, but I think programmer choice is one of
the central qualities that endears C to those who use it. I imagine
that programmers for embedded platforms are in any case perfectly happy
to go on exercising their freedom of choice in this area, given that
not every environment has the luxury of CPU cycles to burn.

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Jan 6 '06 #5

P: n/a
Christopher Benson-Manica said:
Richard Heathfield <in*****@invalid.invalid> wrote:

[snip discussion about initialization of automatic variables]
I'm tempted to agree, but it would diminish programmer choice.


I don't want to be too broad, but I think programmer choice is one of
the central qualities that endears C to those who use it.


Hence the "but".

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jan 6 '06 #6

P: n/a
Madhav wrote:
Hi all,

I did not understand why do the global vars are
initialized to NULL where as the block level variables have random
values? I know that the C standard requires this as was mentioned in a
recent thread.

I want to know why this descrimination is in place. Can't all the
variables be initialised to NULL automatically by the compiler? This
would make programming a little easier.

Regards,
Madhav.


Probably, the origin was only a speed problem. Init the globals at
start of program is not very expensive, just a fill with 0 (at start of
program lots of things are done).
However, init locals each time a function call is done means an
important overwork, not necessary most part of time.

Kind regards.

PS: In some places, a trick is used:
- at first testing stages the globals, stack ... are filled not with
cero but with a very strange value, like H'C5. Reason: if something has
not been init, better to crash as soon as possible, to detect and fix.
- at final version, init is done with cero for the oposite reason.

Jan 6 '06 #7

P: n/a
us****@zevv.nl writes:
Madhav <ma***********@gmail.com> wrote:
I did not understand why do the global vars are
initialized to NULL where as the block level variables have random
values? I know that the C standard requires this as was mentioned in a
recent thread.

I want to know why this descrimination is in place. Can't all the
variables be initialised to NULL automatically by the compiler? This
would make programming a little easier.
No, the data for automatic variables can not be initialized to NULL by
the compiler.


It certainly could be. In fact, a compiler that did so would be
perfectly legal (but it would encourage lazy programmers to depend on
its behavior).
Before main() is called, a system-specific piece of code runs, which
prepares the environment for your C program to run in. One of it's tasks
is to clear the .bss section, e.g. setting all global and static
variables to zero.

Automatic variables are allocated on the stack, and do not have a fixed
address. The same memory locations will often be re-used when entering
and leaving functions. To clean all automatic variables every time a
function or block is entered, your compiler would have to insert a piece
of code at the beginning of *every function* to do that.


As far as the C language is concerned, there's no such thing as a
".bss section", or even a "stack"; they're just particular ways to
implement the semantics required for the language. (Automatic
variables are allocated in a stack-like last-in/first-out fashion, but
there are ways to implement that other than a contiguous linear stack
in memory.)

But I believe the motivation for implicitly initializing global
variables but not automatic variables is based on the kind of
implementation details you're talking about. Global variables are
initialized to 0 converted to the appropriate type; that could be 0,
0L, '\0', 0.0, NULL, etc. In many (most?) implementations, all those
values are represented as all-bits-zero, making it easy to initialize
all the globals by zeroing a contiguous block of memory when the
program is loaded. (If a NULL pointer or a floating-point 0.0 isn't
represented as all-bits-zero, the implementation has to go to some
extra effort, but it already has to handle explicit initializations to
non-zero values anyway.)

Initializing local variables, as you point out, would require some
extra work. The burden on the compiler would be fairly trivial, but
the cost at run-time could be significant -- and it would typically
have been even more significant back when the language was being
designed.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 6 '06 #8

P: n/a
Richard Heathfield a écrit :
us****@zevv.nl said:

No, the data for automatic variables can not be initialized to NULL by
the compiler.

Not so. They could be. They just aren't.

Automatic variables are allocated on the stack, and do not have a fixed
address. The same memory locations will often be re-used when entering
and leaving functions. To clean all automatic variables every time a
function or block is entered, your compiler would have to insert a piece
of code at the beginning of *every function* to do that.

See? I told you it was possible!


The lcc-win32 compiler will init all locals to zero when
called with:
lcc -stackinit 0

By default, lcc-win32 initializes all stack to
0xFFFA5A5A
This provokes many program that use uninitialized variables and run
with other compilers to break down with lcc-win32, what has led
to MANY false bug reports.

Still I think this is worth doing.

jacob
Jan 6 '06 #9

P: n/a
tmp123 a écrit :
Madhav wrote:
Hi all,

I did not understand why do the global vars are
initialized to NULL where as the block level variables have random
values? I know that the C standard requires this as was mentioned in a
recent thread.

I want to know why this descrimination is in place. Can't all the
variables be initialised to NULL automatically by the compiler? This
would make programming a little easier.

Regards,
Madhav.

Probably, the origin was only a speed problem. Init the globals at
start of program is not very expensive, just a fill with 0 (at start of
program lots of things are done).
However, init locals each time a function call is done means an
important overwork, not necessary most part of time.

Kind regards.

PS: In some places, a trick is used:
- at first testing stages the globals, stack ... are filled not with
cero but with a very strange value, like H'C5. Reason: if something has
not been init, better to crash as soon as possible, to detect and fix.
- at final version, init is done with cero for the oposite reason.


lcc-win32 will initialize the stack to
0xFFFA5A5A
This is a nan, and provokes crashes when used as a pointer.
If you want another value (include zero)
you call it with
lcc -stackinit 0

jacob
Jan 6 '06 #10

P: n/a
Keith Thompson wrote:
us****@zevv.nl writes:
Madhav <ma***********@gmail.com> wrote:
I did not understand why do the global vars are
initialized to NULL where as the block level variables have random
values? I know that the C standard requires this as was mentioned in a >> recent thread.
I want to know why this descrimination is in place. Can't all

the >> variables be initialised to NULL automatically by the
compiler? This >> would make programming a little easier.

No, the data for automatic variables can not be initialized to NULL
by the compiler.


It certainly could be. In fact, a compiler that did so would be
perfectly legal (but it would encourage lazy programmers to depend on
its behavior).


Some compilers do so, in some modes, notably debug mode. This leads to
the complaint seen sometimes, "my program runs fine in debug mode, but
crashes when I compile in release mode!!!!"


Brian
Jan 6 '06 #11

P: n/a
"Default User" <de***********@yahoo.com> writes:
Keith Thompson wrote:
us****@zevv.nl writes:
> Madhav <ma***********@gmail.com> wrote:
>> I did not understand why do the global vars are
>> initialized to NULL where as the block level variables have random
>> values? I know that the C standard requires this as was mentioned

in a >> recent thread.
>>
>> I want to know why this descrimination is in place. Can't all

the >> variables be initialised to NULL automatically by the
compiler? This >> would make programming a little easier.
>
> No, the data for automatic variables can not be initialized to NULL
> by the compiler.


It certainly could be. In fact, a compiler that did so would be
perfectly legal (but it would encourage lazy programmers to depend on
its behavior).


Some compilers do so, in some modes, notably debug mode. This leads to
the complaint seen sometimes, "my program runs fine in debug mode, but
crashes when I compile in release mode!!!!"


Or they can initialise to a deliberately large non-zero value so as to
more likely provoke an obvious failure.

--

John Devereux
Jan 7 '06 #12

P: n/a
Madhav wrote:
Hi all,

I did not understand why do the global vars are
initialized to NULL where as the block level variables have random
values? I know that the C standard requires this as was mentioned in a
recent thread.

I want to know why this descrimination is in place. Can't all the
variables be initialised to NULL automatically by the compiler? This
would make programming a little easier.

Regards,
Madhav.


Technically, global variables are not "initialized" by the compiler. Program
globals, data segment, variables are either initialized by the programmer, or
by the program loader as it is copied into ram and it's code/data space is
allocated.

There are two exceptions, partially initialized structures and arrays.

For example the compiler will add the initialized data to the program machine
code image emitted to disk padding with NULL all elements you do NOT
initialize in source code.

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

In the above, ii will be set to (int)1, with ll and a[] set to NULL.

char a[32] = "hi";

In the above, a[0] = 'h' a[1] = 'i' and a[2-31] == 0

For uninitialized global variables, the loader(LD) allocates data segment
memory using calloc() which does the "initialization" to NULL for all
elements, and only a reference to type of memory and how many elements are
needed are emitted to the machine code image emitted to disk by the compiler.

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.

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.

For the "compiler" to accomplish what you perceive as a failing, it will need
to insert machine code that runs BEFORE your code does to initialize the
variables declared. This extra code will consume time and may not be needed
if your code simply assigns a value prior to use, such as the initialization
in a for(;;) loop.

Joseph
Jan 7 '06 #13

P: n/a
Joseph Dionne <jd*****@hotmail.com> writes:
Madhav wrote:
Hi all,
I did not understand why do the global vars are
initialized to NULL where as the block level variables have random
values? I know that the C standard requires this as was mentioned in a
recent thread.
I want to know why this descrimination is in place. Can't all
the
variables be initialised to NULL automatically by the compiler? This
would make programming a little easier.
Technically, global variables are not "initialized" by the compiler.
Program globals, data segment, variables are either initialized by the
programmer, or by the program loader as it is copied into ram and it's
code/data space is allocated.


Technically, global variables are implicitly initialized; the
implementation (of which the compiler is a part) can accomplish this
in any convenient manner. Data segments and program loaders are
implementation details that may be used to implement the semantics
required by the language; they're outside the scope of the langauge
and of this newsgroup.
There are two exceptions, partially initialized structures and arrays.

For example the compiler will add the initialized data to the program
machine code image emitted to disk padding with NULL all elements you
do NOT initialize in source code.

struct {
int ii;
long ll;
char a[32];
} gvar = { 1 };
NULL is a macro that expands to a null pointer constant; it doesn't
apply to non-pointer types.
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).
char a[32] = "hi";

In the above, a[0] = 'h' a[1] = 'i' and a[2-31] == 0

For uninitialized global variables, the loader(LD) allocates data
segment memory using calloc() which does the "initialization" to NULL
for all elements, and only a reference to type of memory and how many
elements are needed are emitted to the machine code image emitted to
disk by the compiler.
An implementation could use calloc() to initialize globals that aren't
initialized explicitly, but only for types where zero (or 0.0, or a
null pointer value) is represented as all-bits-zero. Also, it's
unlikely that an implementation would use either calloc() or malloc()
to allocate the space used for global variables, though I suppose it's
possible. (The "heap" is typically distinct from the memory space
used for global and static variables.)
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.
Maybe. There may not be a disk at all.
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.


A stack (in the sense of a contiguously allocated region of memory
that grows and shrinks linearly, typically with a CPU register
dedicated as a top-of-stack pointer) is one way to implement automatic
variables. It's not the only way. I don't believe the word "stack
even appears in the standard.

[snip]

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 7 '06 #14

P: n/a
Keith Thompson wrote:
Joseph Dionne <jd*****@hotmail.com> writes:
Madhav wrote:
Hi all,
I did not understand why do the global vars are
initialized to NULL where as the block level variables have random
values? I know that the C standard requires this as was mentioned in a
recent thread.
I want to know why this descrimination is in place. Can't all
the
variables be initialised to NULL automatically by the compiler? This
would make programming a little easier.
Technically, global variables are not "initialized" by the compiler.
Program globals, data segment, variables are either initialized by the
programmer, or by the program loader as it is copied into ram and it's
code/data space is allocated.

Technically, global variables are implicitly initialized; the
implementation (of which the compiler is a part) can accomplish this
in any convenient manner. Data segments and program loaders are
implementation details that may be used to implement the semantics
required by the language; they're outside the scope of the langauge
and of this newsgroup.


Now you are just being flippant. This group is for discussing c language
programming, and what a compiler does to create the executable object is
pertinent to the OP's post. As I read what he "thought" should happen would
not be a function of compilation, but a feature added in 4th generation languages.

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.

The "advantages" of c standard libraries make it easier for one to write
software, but one could write their own function libraries in the c lexicon
without third party libraries, providing they had an expert understanding of
the target hardware.
There are two exceptions, partially initialized structures and arrays.

For example the compiler will add the initialized data to the program
machine code image emitted to disk padding with NULL all elements you
do NOT initialize in source code.

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

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.
char a[32] = "hi";

In the above, a[0] = 'h' a[1] = 'i' and a[2-31] == 0

For uninitialized global variables, the loader(LD) allocates data
segment memory using calloc() which does the "initialization" to NULL
for all elements, and only a reference to type of memory and how many
elements are needed are emitted to the machine code image emitted to
disk by the compiler.

An implementation could use calloc() to initialize globals that aren't
initialized explicitly, but only for types where zero (or 0.0, or a
null pointer value) is represented as all-bits-zero. Also, it's
unlikely that an implementation would use either calloc() or malloc()
to allocate the space used for global variables, though I suppose it's
possible. (The "heap" is typically distinct from the memory space
used for global and static variables.)

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.

Maybe. There may not be a disk at all.

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.

A stack (in the sense of a contiguously allocated region of memory
that grows and shrinks linearly, typically with a CPU register
dedicated as a top-of-stack pointer) is one way to implement automatic
variables. It's not the only way. I don't believe the word "stack
even appears in the standard.

[snip]

Jan 7 '06 #15

P: n/a
On 2006-01-07, Joseph Dionne <jd*****@hotmail.com> wrote:
Keith Thompson wrote:
Joseph Dionne <jd*****@hotmail.com> writes:
Madhav wrote:

Hi all,
I did not understand why do the global vars are
initialized to NULL where as the block level variables have random
values? I know that the C standard requires this as was mentioned in a
recent thread.
I want to know why this descrimination is in place. Can't all
the
variables be initialised to NULL automatically by the compiler? This
would make programming a little easier.

Technically, global variables are not "initialized" by the compiler.
Program globals, data segment, variables are either initialized by the
programmer, or by the program loader as it is copied into ram and it's
code/data space is allocated.

Technically, global variables are implicitly initialized; the
implementation (of which the compiler is a part) can accomplish this
in any convenient manner. Data segments and program loaders are
implementation details that may be used to implement the semantics
required by the language; they're outside the scope of the langauge
and of this newsgroup.


Now you are just being flippant. This group is for discussing c
language programming, and what a compiler does to create the
executable object is pertinent to the OP's post. As I read what he
"thought" should happen would not be a function of compilation, but a
feature added in 4th generation languages.

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.

The "advantages" of c standard libraries make it easier for one to
write software, but one could write their own function libraries in
the c lexicon without third party libraries, providing they had an
expert understanding of the target hardware.


More than that... Other than basic things like fopen(), fputc(), etc, or
more primitive C-callable functions used by them (nearly all of which
are in stdio.h - and a _lot_ of stdio.h can still be written in C) which
require knowledge of how to access operating system services directly,
the C library can be written entirely in "standalone" C - that is, in
the subset of C which is permitted in programs that are strictly
conforming for freestanding implementation, except without the
restrictions on the identifiers used. More precisely, with said
restrictions turned upside down, since if you're writing the C library,
you're part of the implementation, and thus should be using identifiers
reserved to the implementation rather than those belonging to the user.
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.


However, you _should_ not assign it to non-pointer types, since it can
be ((void*)0)

Here's part of <sys/_null.h> (#included on my system, FreeBSD 6.0, by
any header which is expected to provide a definition for NULL)

#if defined(_KERNEL) || !defined(__cplusplus)
#define NULL ((void *)0)
#else /* !defined(_KERNEL) && defined(__cplusplus)
....

glibc appears to do something similar.
You say potato, I say NULL -- most c developers think zero when
reading NULL.


Yes, but good ones follow "zero" with ", possibly cast to pointer to
void".
Jan 7 '06 #16

P: n/a
Jordan Abel wrote:
On 2006-01-07, Joseph Dionne <jd*****@hotmail.com> wrote:
Keith Thompson wrote:
Joseph Dionne <jd*****@hotmail.com> writes:
Madhav wrote:
>Hi all,
> I did not understand why do the global vars are
>initialized to NULL where as the block level variables have random
>values? I know that the C standard requires this as was mentioned in a
>recent thread.
> I want to know why this descrimination is in place. Can't all
>the
>variables be initialised to NULL automatically by the compiler? This
>would make programming a little easier.

Technically, global variables are not "initialized" by the compiler.
Program globals, data segment, variables are either initialized by the
programmer, or by the program loader as it is copied into ram and it's
code/data space is allocated.
Technically, global variables are implicitly initialized; the
implementation (of which the compiler is a part) can accomplish this
in any convenient manner. Data segments and program loaders are
implementation details that may be used to implement the semantics
required by the language; they're outside the scope of the langauge
and of this newsgroup.


Now you are just being flippant. This group is for discussing c
language programming, and what a compiler does to create the
executable object is pertinent to the OP's post. As I read what he
"thought" should happen would not be a function of compilation, but a
feature added in 4th generation languages.

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.

The "advantages" of c standard libraries make it easier for one to
write software, but one could write their own function libraries in
the c lexicon without third party libraries, providing they had an
expert understanding of the target hardware.

More than that... Other than basic things like fopen(), fputc(), etc, or
more primitive C-callable functions used by them (nearly all of which
are in stdio.h - and a _lot_ of stdio.h can still be written in C) which
require knowledge of how to access operating system services directly,
the C library can be written entirely in "standalone" C - that is, in
the subset of C which is permitted in programs that are strictly
conforming for freestanding implementation, except without the
restrictions on the identifiers used. More precisely, with said
restrictions turned upside down, since if you're writing the C library,
you're part of the implementation, and thus should be using identifiers
reserved to the implementation rather than those belonging to the user.

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.

However, you _should_ not assign it to non-pointer types, since it can
be ((void*)0)

Here's part of <sys/_null.h> (#included on my system, FreeBSD 6.0, by
any header which is expected to provide a definition for NULL)

#if defined(_KERNEL) || !defined(__cplusplus)
#define NULL ((void *)0)
#else /* !defined(_KERNEL) && defined(__cplusplus)
...

glibc appears to do something similar.

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

Yes, but good ones follow "zero" with ", possibly cast to pointer to
void".


I surrender! Since I never use NULL in my code, choosing to use a (cast)0
where cast is "int *", "char *", etc, you win.

Furthermore, "int ii = NULL" in C99 compilers and above (at least) started to
generate a warning about type violations, you hold the higher ground in the
argument.
Jan 7 '06 #17

P: n/a
Joseph Dionne <jd*****@hotmail.com> writes:
Keith Thompson wrote:
Joseph Dionne <jd*****@hotmail.com> writes: [...]
Technically, global variables are not "initialized" by the compiler.
Program globals, data segment, variables are either initialized by the
programmer, or by the program loader as it is copied into ram and it's
code/data space is allocated. Technically, global variables are implicitly initialized; the
implementation (of which the compiler is a part) can accomplish this
in any convenient manner. Data segments and program loaders are
implementation details that may be used to implement the semantics
required by the language; they're outside the scope of the langauge
and of this newsgroup.


Now you are just being flippant.


Not at all.
This group is for discussing c
language programming, and what a compiler does to create the
executable object is pertinent to the OP's post. As I read what he
"thought" should happen would not be a function of compilation, but a
feature added in 4th generation languages.
The specific methods that particular compilers use to implement the
required semantics of the C language are mostly off-topic, though a
general discussion of how those semantics are implemented could be
topical. It's appropriate (IMHO) to mention that stacks, heaps, data
segments, ".bss" segments, program loaders and so forth are common
techniques, but asserting that they are *the* way the language is
implemented is both inapproprate and inaccurate.
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.
I don't think that's particularly accurate, but it's beside the point.

[...]
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.


There's a big difference between "every C compiler you've used" and
"every C compiler". NULL is defined to expand to a null pointer
constant. I commonly use implementations where NULL expands to
((void*)0). Using NULL for anything other that a pointer is wrong,
though it may happen to "work" in some implementations.

You really need to understand that pointers and integers are two
different things.
You say potato, I say NULL -- most c developers think zero when reading NULL.


No.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 7 '06 #18

P: n/a
On Sat, 07 Jan 2006 23:32:53 GMT, in comp.lang.c , Joseph Dionne
<jd*****@hotmail.com> wrote:

(and didn't snip any of 101 lines)
I surrender!


Can you also please learn to trim posts a little? You can remove
anything not relevant to your reply.

Mark McIntyre
--

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Jan 8 '06 #19

P: n/a
Mark McIntyre wrote:
On Sat, 07 Jan 2006 23:32:53 GMT, in comp.lang.c , Joseph Dionne
<jd*****@hotmail.com> wrote: [..]
Mark McIntyre


Yes
Jan 8 '06 #20

P: n/a
In article <tw*****************@newsread3.news.atl.earthlink. net>
Joseph Dionne <jd*****@hotmail.com> wrote:
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.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Jan 8 '06 #21

P: n/a
Joseph Dionne wrote:
Keith Thompson wrote:
Joseph Dionne <jd*****@hotmail.com> writes:
.... 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/>
Jan 8 '06 #22

P: n/a
"Chuck F. " <cb********@yahoo.com> writes:
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.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 8 '06 #23

P: n/a
Keith Thompson said:
"Chuck F. " <cb********@yahoo.com> writes:

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.


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

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jan 8 '06 #24

P: n/a
In article <Q-********************@maineline.net>,
Chuck F. <cb********@maineline.net> wrote:
....
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.

Jan 8 '06 #25

P: n/a
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.org> wrote:
....
I have the same suspicion; he exhibits a rare combination of wrongness
and certainty.


You misspelled "disagreement".

Jan 8 '06 #26

P: n/a
On Fri, 6 Jan 2006 10:39:02 +0000 (UTC), Richard Heathfield
<in*****@invalid.invalid> wrote:
Madhav said:

I want to know why this descrimination is in place.


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
Jan 11 '06 #27

P: n/a
On Sat, 07 Jan 2006 22:55:18 GMT, Joseph Dionne <jd*****@hotmail.com>
wrote:
<snip>
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
Jan 16 '06 #28

This discussion thread is closed

Replies have been disabled for this discussion.