int x;
static int y;
int *p;
Note that these are all uninitialized, but have static storage
duration (i.e., exist for the lifetime of the entire program),
so are *effectively* initialized as if with "= { 0 }". The
variables have different linkages: x and p have external linkage,
while y has internal linkage.
int main(void)
{
int i;
int j=9;
int *ptr;
These all have automatic duration. The variable named j is
initialized (to 9) and the other two are not.
The entity named "str", of type "pointer to char", has automatic
duration. It is initialized, and points to an array created by
the compiler. The array created by the compiler may (or may not)
live in read-only memory, but has type char [7] (not the "obviously
correct" type of const char [7] -- in C++ it has this type, but not
in C). The array has static duration, and is initialized to contain
{'G', 'O', 'O', 'G', 'L', 'E', '\0'} (hence the size of 7).
The variable "a" has static duration, and is not initialized here,
so is effectively initialized to zero, as if with "= { 0 }".
The array named "k" is missing a size (and is not initialized), which
is a constraint violation, and a diagnostic is required.
The array named "q" is initialized, so its size is computed from
the initializers. It has automatic duration. This declaration is
valid in C99, which allows initializers for automatic-duration
arrays, but not in C89, which does not. If you have a C89 compiler,
a diagnostic is required (of course a single diagnostic for both
the error for the array k and the error for the array q suffices,
although a good compiler will produce two separate diagnostics).
register int reg;
volatile int vol;
These two have automatic duration (and are uninitialized).
......
....
...
return 0;
}
According to my knowledge the variables declared in the above program
are stored as follows:
GLOBAL VAR's:
You need to define what you mean by "global". Some people use this
to mean "any object with static duration", while others use it to
mean "variables that have external linkage". You appear to be doing
the former (which is in my experience not as common as the latter):
x,y are stored in INITIALISED PART OF DATA SEGMENT.
*p is stored in STACK SEGMENT.
These are possible but unlikely. The C Standard says only that
they have static duration -- i.e., that they exist as long as the
C program runs. One way to do that is to put them all on "the
stack" (whatever that may be!) before making the initial call to
main(). In this case, they would all be "stack" variables.
More commonly, however, all three live in a "data segment", but
all three are in the "uninitialized" part of that data segment,
sometimes referred-to as a "bss segment" instead.
(Referring to p as "*p" is also questionable, or at least, a sign
that you have not thought things through here. In particular, p
has type "pointer to int", and -- thanks to its default initialization
because of its static duration -- initial value NULL. The variable
"p" itself thus has a value, but following the pointer value via
"*p" is not valid[%], because the value stored in p is not pointing
to an actual, existing "int". If you set p to point to some "int",
*p becomes valid for as long as that "int" exists. Use a
static-duration object, and *p will be valid as long as p points
to that object; use an automatic-duration object, and *p will be
valid only as long as (a) p points to it and (b) the object itself
is still "alive". The object "dies" when its enclosing block is
terminated.)
[% Following this invalid NULL pointer generally does one of three
things:
"segmentation fault - core dumped" (on most Unix-like systems
such as Linux, and many other protected systems)
is OK to read, producing some semi-predictable value, such
as the first instruction in the program or a copyright string
or some such, but writing to it produces a runtime trap
(perhaps the same "segmentation fault", or "bus error", or
some other machine-specific diagnostic, such as a Blue Screen
of Death or a reboot)
is OK to read and write, but writes are silently ignored
Standard C does not require any of these behaviors, and depending
on any of them is unwise.]
LOCAL VAR's:
all variables are stored in STACK SEGMENT.
Probably, but again, the C Standard does not say so. On at least
a few implementations, there is no separate "stack segment", as
there is no single system-supplied stack. (Either there are multiple
stacks, as on some systems, or there are no distinguished "stacks"
at all, as on others. In the latter case, the C system usually
uses dynamically-allocated space -- sometimes referred to as "the
heap", or sometimes called "free store"; there are some more
less-common names as well -- to create a linked list that functions
in a stack-like manner.)
There is a secondary problem with thinking this way, and that
has to do with those objects that are actually stored in machine
registers (the one named "reg" is perhaps slightly more likely
to be one of these, although modern compilers tend to put as
many variables into registers as possible anyway). The machine
registers are not part of a typical machine's "stack segment",
although in some cases, space is reserved within various stack
frames to hold register values at various times. In that sense,
they may or may not be in a (or the) "stack segment" at any
given point: a variable that is in a register for 10 lines of
code may get written into the stack after those 10 lines, then
taken back into the register 15 lines of code later. It is
thus "on the stack" only sometimes, not all the time.
In summary: if you do not want to be pinned forever to specific
*implementations* of C, avoid making assumptions about "where the
variables live". If you rely only on those things *guaranteed* in
Standard C, your code will work on every Standard C system ever
made. If you rely on things only guaranteed for the Frobozz system,
you may be stuck with the Frobozz system five years from now. Of
course, this is a tradeoff: there is much that is difficult or even
impossible to do only in Standard C, and easy or at least possible
if you limit yourself to particular systems. Just make sure you
know what you are trading: are the magic beans really worth giving
up the cow?