[comp.lang.c] Just above and below main

stealth@nanometrics.portal.UUCP (Steve Sabram) (04/10/91)

Ok, we got a big debate here at work about
the folowing piece of code;
_________________________

int outside;

main()
{
int inside;
...
}

_________________________

Just what are the differences
between these two variables?
 
We all agree that "outside" is
a global and thus accessable
to all functions in this file
while "inside" is accessable 
only to everything in main().

Our debate is which one of these 
two are initialized to zero if
any.  This is important
to us since we are coding for
a microcontroller and ROMing
the code.  We are detecting 
cold or warm resets with the 
varable "outside".  We just 
want to make sure if this is just
to this complier or a part of ANSI.




-- 
   ________   ______     
  (___  ___) (___    Stephen R. Sabram -- engineering dude |Nanometrics, Inc
______) \________)       stealth@nanometrics.portal.com    |Sunnyvale, CA 

mattl@ritcsh.csh.rit.edu (FaceMan) (04/10/91)

In article <1243@nanometrics.UUCP> stealth@nanometrics.portal.UUCP (Steve Sabram) writes:
>Ok, we got a big debate here at work about
>the folowing piece of code;
>_________________________
>
>int outside;
>
>main()
>{
>int inside;
>...
>}
>
>_________________________
>
>Just what are the differences
>between these two variables?
> 
>We all agree that "outside" is a global and thus accessable
>to all functions in this file while "inside" is accessable 
>only to everything in main().

The difference between inside and outside is where they are stored.
Since "outside" is outside of any functions, it will be allocated to main
memory. "Inside", on the other hand, is inside the function "main()", and
will be allocated on the stack. This should mean that "outside" should
start out with a value of zero (though there may be a compiler out there
that does clean out main memory for you), while inside will have an initial
value of whatever happens to be at that location on the stack (in other
words, garbage)...


-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
mattl@ritcsh.csh.rit.edu ! Swapping memory to disk is virtually indespensible..
mal6315@ultb.rit.edu     ! ----------------------------------------------------
mal6315@RITVAX           ! new book: "#define art of C programming..."

wolfram@cip-s08.informatik.rwth-aachen.de (Wolfram Roesler) (04/12/91)

stealth@nanometrics.portal.UUCP (Steve Sabram) writes:

>_________________________

>int outside;

>main()
>{
>int inside;
>...
>}

>_________________________


>We all agree that "outside" is
>a global and thus accessable			Exactly.
>to all functions in this file
>while "inside" is accessable 
>only to everything in main().

>Our debate is which one of these 
>two are initialized to zero if
>any.
None of them is. The major difference is that the vars lie in different places
in memory. Outside is placed in the data segment of the program and inside in
on the heap of the funtion main. None of both is intialised to anything unless
you tell cc to do so:
	int outside=0;
will initialise outside to 0 on prg start, and
	int inside=0;
will initialise inside to 0 whenever main is called (ok main is called only
once but this is valid for other functions too of course).
To make inside keep its value during multiple calls of the function it is
in, use
	static int inside=0;
this will place inside in the data seg just like it was a global, but it will
be accessible from the function it is in only. The initialisation will take
place only once at the start of the prg.
This is a highly recommended way to avoid globals.

More, the outside variable is not only accessible from all functions of the
file it is in but from all files linked together. The other files simply have
to say
	extern int outside;
and they can do all they want to the variable. To hide outside from other
modules and to make it accessible to the current file only, use
	static int outside;

For further info RTFM.

Hope to have helped you
Okami-san

volpe@camelback.crd.ge.com (Christopher R Volpe) (04/12/91)

In article <wolfram.671458575@cip-s08>,
wolfram@cip-s08.informatik.rwth-aachen.de (Wolfram Roesler) writes:
|>stealth@nanometrics.portal.UUCP (Steve Sabram) writes:
|>
|>>_________________________
|>
|>>int outside;
|>
|>>main()
|>>{
|>>int inside;
|>>...
|>>}
|>
|>>_________________________
|>
|>
|>>Our debate is which one of these 
|>>two are initialized to zero if
|>>any.
|>None of them is. 

Um, no. outside is initialized to zero.

|>
|>For further info RTFM.
|>

Good idea.

-Chris
                                                     
==================
Chris Volpe
G.E. Corporate R&D
volpecr@crd.ge.com

browns@iccgcc.decnet.ab.com (Stan Brown) (04/13/91)

In article <1243@nanometrics.UUCP>, stealth@nanometrics.portal.UUCP (Steve Sabram) writes:
> Ok, we got a big debate here at work about
> the folowing piece of code;
> _________________________
> 
> int outside;
> 
> main()
> {
> int inside;
> ....
> }
> 
> _________________________
> 
> Just what are the differences between these two variables?
>  
> We all agree that "outside" is a global and thus accessable
> to all functions in this file while "inside" is accessable 
> only to everything in main().

"outside" is also accessible to any function in any other source file
if the function (or the source file) contains "extern int outside;"
> 
> Our debate is which one of these two are initialized to zero if
> any.  This is important to us since we are coding for
> a microcontroller and ROMing the code.  We are detecting 
> cold or warm resets with the varable "outside".  We just 
> want to make sure if this is just to this complier or a part of ANSI.

Sec 3.5.7 of the ANSI standard: "If an object that has automatic storage
duration is not initialized explicitly, its value is indeterminate.  If
an object that has static storage duration is not initialized
explicitly, it is initialized implicitly as if every member that has
arithmetic type were assigned 0 ...."

So "outside" is initialized to 0 and "inside" is not.  ("Static storage
duration" covers more than just variables declared static.)

However, if you're expecting external events to change "outside"
then you need to declare it volatile and you have no guarantee
that the program's initialization is the most recent store to 
the variable by the time the first line of your main function
is executed.  (See sec 3.1.2.4).

Stan Brown, Oak Road Systems, Cleveland, Ohio, USA    +1 216 371 0043
                   email (until 91/4/30): browns@iccgcc.decnet.ab.com
My opinions are mine:  I don't speak for any other person or company.

gwyn@smoke.brl.mil (Doug Gwyn) (04/13/91)

In article <1243@nanometrics.UUCP> stealth@nanometrics.portal.UUCP (Steve Sabram) writes:
>Our debate is which one of these two are initialized to zero if any.

The variable with static storage duration, having no explicit initializer,
is implicitly initialized to a zero value of the appropriate type.

The variable with automatic storage duration is not implicitly initialized
to anything; it should be assumed to contain garbage upon each entry to
the block in which it is declared.

gregory@ritcsh.csh.rit.edu (Greg Conway) (04/13/91)

In article <1243@nanometrics.UUCP> stealth@nanometrics.portal.UUCP (Steve Sabram) writes:
>int outside;
>
>main()
>{
>int inside;
>...
>}

>Our debate is which one of these 
>two are initialized to zero if
>any.  


The answer you are looking for is in K&R II, section 4.9, paragraph 2.
I found it in the index under "Externals, initialization of". 


-- 
		Gregory Conway @ Computer Science House, RIT
          "And the man in the mirror has sad eyes..."    - Marillion

jseymour@medar.com (James Seymour) (04/13/91)

In article <18473@crdgw1.crd.ge.com> volpe@camelback.crd.ge.com (Christopher R Volpe) writes:
|In article <wolfram.671458575@cip-s08>,
|wolfram@cip-s08.informatik.rwth-aachen.de (Wolfram Roesler) writes:
||>stealth@nanometrics.portal.UUCP (Steve Sabram) writes:
||>
||>>_________________________
||>
||>>int outside;
||>
||>>main()
||>>{
||>>int inside;
||>>...
||>>}
||>
||>>_________________________
||>
||>
||>>Our debate is which one of these 
||>>two are initialized to zero if
||>>any.
||>None of them is. 
|
|Um, no. outside is initialized to zero.
|
||>
||>For further info RTFM.
||>
|
|Good idea.
|

Very good idea.  Better yet, the manual specific to the compiler package
*you* are using.  On some older compilers, you needed to explicitly
initialize globals in the file they were intended to be *defined* in.  All
other occurances of things like the declaration of "outside" (as above)
were assumed to be a reference to an external that was defined in another
file.  If you didn't have a global initialized at least once, the symbol
for it was never defined, and thus the link phase would fail.  In newer
compilers however, declarations like that in the original question above
result in "outside" being global, it is defined in the file that contains
the above declaration (it is not preceded with the word "extern"), and the
space it occupies is initialized to zero.  Regardless of what newer
compilers do with globals however, IMHO it is best to explicitly initialize
such variables if you expect them to start with a known value - even 0.
Self-documenting code is a good practice.  Now, "inside" is local to the
function main and is an "auto" variable (it's space is on the stack), thus
it is un-initialized (will contain whatever was in the portion of memory
occupied by that variable when the stack frame is allocated at run-time).

-- 
Jim Seymour				| Medar, Inc.
...!uunet!medar!jseymour		| 38700 Grand River Ave.
jseymour@medar.com			| Farmington Hills, MI. 48331
CIS: 72730,1166  GEnie: jseymour	| FAX: (313)477-8897

volpe@camelback.crd.ge.com (Christopher R Volpe) (04/15/91)

In article <111@hdwr1.medar.com>, jseymour@medar.com (James Seymour) writes:
|>Very good idea.  Better yet, the manual specific to the compiler package
|>*you* are using.  On some older compilers, you needed to explicitly
                            ^^^^^
By "older" I assume you mean "broken"???

|>initialize globals in the file they were intended to be *defined* in.  All
|>other occurances of things like the declaration of "outside" (as above)
|>were assumed to be a reference to an external that was defined in another
|>file.  If you didn't have a global initialized at least once, the symbol
|>for it was never defined, and thus the link phase would fail.

The behavior you are describing does not correspond to the C language
described either by ANSI or by K&R1. It doesn't make much sense to
point out every possible way a compiler can do the wrong thing whenever
you tell someone what the language guarantees, IMHO.

|>  In newer
|>compilers however, declarations like that in the original question above
|>result in "outside" being global, it is defined in the file that contains
|>the above declaration (it is not preceded with the word "extern"), and the
|>space it occupies is initialized to zero.  Regardless of what newer
|>compilers do with globals however, IMHO it is best to explicitly initialize
|>such variables if you expect them to start with a known value - even 0.

Agreed.

|>-- 
|>Jim Seymour				| Medar, Inc.
|>...!uunet!medar!jseymour		| 38700 Grand River Ave.
|>jseymour@medar.com			| Farmington Hills, MI. 48331
|>CIS: 72730,1166  GEnie: jseymour	| FAX: (313)477-8897
                                                       
==================
Chris Volpe
G.E. Corporate R&D
volpecr@crd.ge.com