469,326 Members | 1,452 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,326 developers. It's quick & easy.

Global variable and static global variable

I heard that all global variables are static..

If its so then what is the difference between the 2 declarations:
Expand|Select|Wrap|Line Numbers
  1. #include<stdio.h>
  2.  
  3. int a;
  4. static int b;
  5.  
  6. main()
  7. {
  8. ....
  9. }
  10.  
What is the difference between there visibility and how long they remain in memory?
Jan 7 '09 #1
25 119020
Banfa
9,064 Expert Mod 8TB
They are both in memory for the entire lifetime of the program. The variable that is declared static only has scope in the file in which it is declared where as the variable declared without static can be accessed from other files using an extern declaration.
Jan 7 '09 #2
donbock
2,422 Expert 2GB
The meaning of the "static" keyword in C depends on whether or not it appears within a brace-delimited block. Refer to the following code snippet.
Expand|Select|Wrap|Line Numbers
  1. int a;
  2. static int b;
  3.  
  4. int func(void) {
  5.    int c;
  6.    static int d;
  7.    ...
  8. }
Variables 'a' and 'b' are declared outside of any brace-delimited blocks, therefore they both persist for the life of the program and are accessible from anywhere in the compilation unit. In this case, the "static" keyword has the effect of making variable 'b' local to the compilation unit. Variable 'a' can be accessed from any other compilation units that contain an extern declaration for it.

Variables 'c' and 'd' are declared within a brace-delimited block, therefore they are only accessible from within that block. In this case, the "static" keyword has the effect of making variable 'd' persist for the life of the program. Variable 'c' only persists while execution is within that brace-delimited block. There is no reason to expect variable 'c' to be stored at the same location for successive executions of the brace-delimited block.

I would expect C++ to be consist with C in this regard, but I don't know that for a fact.
Jan 7 '09 #3
Banfa
9,064 Expert Mod 8TB
It is the same in C++
Jan 7 '09 #4
donbock
2,422 Expert 2GB
One last note. Neither variable 'c' nor 'd' are accessible from other compilation units. Any attempt to add an extern declaration for either of them to another compilation unit will result in a link error.

(Banfa: thanks for fixing my typo!)
Jan 7 '09 #5
weaknessforcats
9,208 Expert Mod 8TB
C++ is consistent with C as faras the static keyword is concerned. However, in C++ the static keyword is largely deprecated and is in the language generally for backwards compatibility with C. There remain some uses of it, however.

No one has mentioned linkage so far, which is odd. Linkage comes in two flavors, external and internal. External linkage means the variable or function is accessible (sharable) from outside the compilation unit. Internal linkage means the variable/function is accessible onlt from inside the compilation unit.

So a static function cannot be called from outside the compilation unit but an external one can:
Expand|Select|Wrap|Line Numbers
  1. extern void MyFunction(int arg)
  2. {
  3.     /* etc... */
  4. }
  5.  
The function prototype is:
Expand|Select|Wrap|Line Numbers
  1. extern void MyFunction(int arg);
The extern is the default. External functions (aka global functions) are callable by using the function prototype.

Static functions cannot be called from outside the compilation unit:
Expand|Select|Wrap|Line Numbers
  1. static void MyFunction(int arg)
  2. {
  3.     /* etc... */
  4. }
  5.  
The function prototype is:
Expand|Select|Wrap|Line Numbers
  1. static void MyFunction(int arg);
You may place the static function prototype at the top of the file but the definition of the function must reside somewhere in the file.

The above applies to variables.
Expand|Select|Wrap|Line Numbers
  1. extern int value;
This variable is accessible from another compilation unit by:
Expand|Select|Wrap|Line Numbers
  1. extern int value;
Static variables have internal linkage and are accessible only in the current scope. If the static variable is inside a function, it is accesssible only from inside the function. Here the static keyword also causes the local variable to persist after the function completes execution. It's kind of like a local global.
Jan 7 '09 #6
ok i understood it. thanks for your support.
Jan 9 '09 #7
vamskk
3
Global static variables are accessable from other files. The static is to make the variable retain the last assigned value. But what is given below says global static variables are not accesable from other file.

ex.
http://knol.google.com/k/vivek-bhadr...4lj4klzp0d/36#





@donbock
Jun 24 '09 #8
JosAH
11,448 Expert 8TB
@vamskk
Nowhere in this (old) thread it is written that global static variables would be accessible from other translation units. Global static variables don't have external linkage. Of course their address can be passed around at will.

btw, in that blog function main is written as 'void main()', that is a strong indication to me that the blogger doesn't know much about C or C++. Don't take that blog as the truth.

kind regards,

Jos
Jun 24 '09 #9
vamskk
3
The link that is given discusses about can static global variables be defined in .h file and the answer is yes. So that should not matter if it is defined in a .c file and would be accesable from another file in the same project using extern.

May be the information given is not authentic. Thank you JOASH.

Could you give some authentic links for global static variables and its definition.

Thanks and Regards,
Vamskk
Jun 24 '09 #10
donbock
2,422 Expert 2GB
@vamskk
I recommend you avoid the phrase global static variable. This is a Cheshire Cat term: it means what you want it to mean -- a condition ripe for confusion. Using the language of the Standard may be pedantic, but it is precise and unambiguous.


An identifier declared in different scopes or in the same scope more than once can be made to refer to the same object or function by a process called linkage. There are three kinds of linkage: external, internal, and none.

In the set of translation units and libraries that constitutes an entire program, each declaration of a particular identifier with external linkage denotes the same object or function. Within one translation unit, each declaration of an identifier with internal linkage denotes the same object or function. Each declaration of an identifier with no linkage denotes a unique entity.

If the declaration of a file scope identifier for an object or a function contains the storage class specifier static, the identifier has internal linkage.

For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible, if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage.

If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier extern. If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.

The following identifiers have no linkage: an identifier declared to be anything other than an object or a function; an identifier declared to be a function parameter; a block scope identifier for an object declared without the storage-class specifier extern.

If, within a translation unit, the same identifier appears with both internal and external linkage, the behavior is undefined.

An object has a storage duration that determines its lifetime. There are three storage durations: static, automatic, and allocated. Allocated storage is described in 7.20.3 [Memory management functions: calloc, free, malloc, realloc].

The lifetime of an object is the portion of program execution during which storage is guaranteed to be reserved for it. An object exists, has a constant address, and retains its last-stored value throughout its lifetime. If an object is referred to outside of its lifetime, the behavior is undefined. The value of a pointer becomes indeterminate when the object it points to reaches the end of its lifetime.

An object whose identifier is declared with external or internal linkage, or with the storage-class specifier static has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.

An object whose identifier is declared with no linkage and without the storage-class specifier static has automatic storage duration.

For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way. (Entering an enclosed block or calling a function suspends, but does not end, execution of the current block.) If the block is entered recursively, a new instance of the object is created each time. The initial value of the object is indeterminate. If an initialization is specified for the object, it is performed each time the declaration is reached in the execution of the block; otherwise, the value becomes indeterminate each time the declaration is reached.

For such an object that does have a variable length array type, its lifetime extends from the declaration of the object until execution of the program leaves the scope of the declaration. If the scope is entered recursively, a new instance of the object is created each time. The initial value of the object is indeterminate.
Notice that linkage applies to identifiers while storage duration applies to objects.

All the confusion arises because the same keyword, static, indicates both linkage and storage duration.

I suppose you intended the phrase global static variable to mean an object with static storage duration whose identifier has internal linkage.

This exposition is consistent with the explanations already provided for this [old] thread. The difference is that I've been deliberately pedantic.
Jun 24 '09 #11
Tassos Souris
152 100+
@vamskk
Let's say that we have a file defs.h that has a "static global" variable like you call it.
In file main.c you include defs.h so what actually happens is that the variable is defined within the main.c file and that brings us to the case discussed in this topic.
Nothing strange.
Jun 24 '09 #12
vamskk
3
In a proj all .c files concerning to that project are compiled together. Is it not as good as they are like include files? So global static variable from other .c file can be accessed by extern command. Is it not so?
Jun 25 '09 #13
donbock
2,422 Expert 2GB
@vamskk
No. Each .c file is compiled separately into its own .o file; then all of the .o files are linked together.

It is possible for one .c file to #include all of the other .c files -- the preprocessor doesn't know any better. However nobody does that. It would look very odd.

@vamskk
Since each .c file is compiled separate, then each is considered a separate compilation unit. Only external linkage can bridge compilation units; and then only if both compilation units declare the variable with extern.

PS. I have this sneaking suspicion that "compilation unit" is not the pedantic term. Don't have my copy of the Standard handy to check. Hopefully you know what I mean.
Jun 25 '09 #14
@JosAH
================================================== =======

a static variable defined in the global space in a file cannot be accessed from other files because it doesn't have an external linkage. the example I have given exactly says that. look below for once again:

/*Illegal use of static variable*/
/*File: test1.c*/
#include<stdio.h>
#include "header.h"
int i = 100;
int main() {
printf("This is the scope of the global variable:%d\n",i);
foo();
foo();
printf("This is not a scope of static variable:%d\n",j);
return 0;
}
/*File: test2.c*/
extern int i;
static int j = 200;
int foo() {
printf("This is the scope of the global variable: %d\n",i);
j++;
printf("in func foo() the scope of static j is: %d\n",j);
return 0;
}
/*File: header.h*/
extern int foo();
extern int j;

Error:

/tmp/cckXvIiw.o(.text+0x2f): In function `main':
: undefined reference to `j'

the above example exactly clears up your confusion. the variable 'j' has been declared as static in file 'test2.c' and 'test1.c' tries to access it as extern which the gcc compiler complain as : "undefined reference to `j' ".

now if you declare it( 'j' ) in a header file as static then what happens is:
"whenever that header file in included in a '.c' file a new memory is allocated for that variable for that particular file. Which essentially means that different files will use their respective copies of the file during the program execution. So the real significance of the static storage class vanishes when it's declared in a header file. "

for further information please refer

http://knol.google.com/k/vivek-bhadr...4klzp0d.dcc4tn
================================================== =======
>>"in that blog function main is written as 'void main()', that is a strong indication to me that the blogger doesn't know much about C or C++"

Take no offense, I really donno the big deal with 'void main()' and 'int main()' and how does it really confirm a person's C/C++ knowledge ? anyways, thanks for passing the information. at least now I can judge a person's C/C++ capabilities in a moment :-)

cheers
-Vivek
Jun 25 '09 #15
JosAH
11,448 Expert 8TB
@vivekbhadra
That is so wrong; a C compiler doesn't know anything about header files; that's a task for the preprocessor; the compiler just works with translation units; one at the time. If you define a static variable in a header file it'll end up in every translation unit that includes that file and therefore multiple static variables will exist.

kind regards,

Jos
Jun 25 '09 #16
@JosAH
================================================== =========
and you don't want multiple copies of your static variable... right ? why does one in the first place declare a variable as a static variable in a header file ? one can only do that assuming this would be unique across the compilation units and so ( by mistake of course). but otherwise there can be no sesible reason on wants to declare something as static in a header file. that's what I have written in the blog. I have never said the compiler would complain about it but have said this would create multiple copies of the same static variable in different files. so ultimately the meaning of static doesn't hold good. let me know if there is still any confusion about it.

Please read it once again:
What happens when a static variable is declared in a header file?
Of course we can declare a static variable in a header file, include that header file in .c files and access the variable from the .c files. But important thing to remember here is the fact that if a static variable is declared in a header file, then whenever that header file in included in a '.c' file a new memory is allocated for that variable for that particular file. Which essentially means that different files will use their respective copies of the file during the program execution. So the real significance of the static storage class vanishes when it's declared in a header file.
Look at the following example(pleas elet me know which line in the following snippet is actually bothering you):

test.h
static int var;
test.c
#include<stdio.h>
#include "test.h"
extern int foo();
void main(void)
{
printf("var in %s: %d\n ", __FILE__, ++var);
foo();
}
helper.c
#include "test.h"
void foo(void)
{
printf("var in %s: %d\n",__FILE__, ++var);
}

Compilation:

gcc -o statictest test.c helper.c

Run:

./statictest
Output:
~/test $ ./statictest
var in test.c: 1
var in helper.c: 1


Now lets see the sysmbol table of "statictest" particularly focussing on how "var" variable to understand how compiler generates code for "var".
00000000 l df *ABS* 00000000 test.c
080496c8 l O .bss 00000004 var
00000000 l df *ABS* 00000000 helper.c
080496cc l O .bss 00000004 var

However if we change the declaration in the test.h file and make the var a global variable then the whole thing changes as below:

test.h
int var;
Compilation:
gcc -o globaltest test.c helper.c
Run:
./statictest
Output:
~/test $ ./statictest
var in test.c: 1
var in helper.c: 2


Symbol table of "globaltest" only contains a single entry for 'var':
080496c8 g O .bss 00000004 var

================================================== =====
What I can guess is in the line "So the real significance of the static storage class vanishes when it's declared in a header file." the word significance is probably bothering you. I have written significance more from a programming perspective not from a compiler. The variable still will retain it's value because it either from the Data Section or from the BSS but for a programmer, if he is thinking this would be unique across the program is incorrect. About the multiple copies of it I have clearly mention in the line "Which essentially means that different files will use their respective copies of the file during the program execution.".
Jun 25 '09 #17
JosAH
11,448 Expert 8TB
[quote=vivekbhadra;3496072]Look at the following example(pleas elet me know which line in the following snippet is actually bothering you):

Expand|Select|Wrap|Line Numbers
  1.         void main(void)
  2.  
There's no need to explain the semantics of the word 'static' to me; I know what it is. Defining (not "declaring") a static variable in an header file is just plain stupid and nothing of its meaning "vanishes".

kind regards,

Jos
Jun 25 '09 #18
[quote=JosAH;3496086] @vivekbhadra
================================================== ===
>>There's no need to explain the semantics of the word 'static' to me; I know what it is.

so as I do ..... and just one more information when you are talking about a header file it's always declaration not definition .... until the header file is included in a C/C++ file it never gets it's memory allocated ... so it's a declaration in a header file not definition ...

anyway somehow I realize this conversation is going a little strange ... lets stop it .... your knowledge is not a sufficient proof of other people's ignorance .... good luck and goodbye
Jun 25 '09 #19
JosAH
11,448 Expert 8TB
[quote=vivekbhadra;3496087] @JosAH
When you do:

Expand|Select|Wrap|Line Numbers
  1. static int foo;
  2.  
anywhere (not just in a header file) it's a definition and it's tentative. You have managed to obfuscate an old thread that was crystal clear before. Please don't do that but get your facts straight before you post.

kind regards,

Jos
Jun 25 '09 #20
[quote=JosAH;3496091] @vivekbhadra
================================================== ====
>>anywhere (not just in a header file) it's a definition and it's tentative.

nothing is tentative in the C paradigm unless you have created your own . there is absolutely no confusion about the fact that unless a header file is included in a C file a declaration never gets into a definition as it doesn't still have a memory allocated. your repeated shout doesn't really get the variable a memory and hence it still remains a declaration. and when this header file is included in a file this variable is declared as well as defined at the same place. so there is nothing wrong in saying declaring a static variable in a header file. the matter of fact is that I have all my facts straight but probably you gotta little bit straighten your professional manners. there has been no obfuscation by my thread whatsoever. please read the link below to understand a declaration, a definition and a declaration as well as a definition.
http://www-ee.eng.hawaii.edu/~tep/EE...on2.1.1.4.html

cheers
vivek
Jun 25 '09 #21
JosAH
11,448 Expert 8TB
Straight from the C Standard:

3.7.2 External object definitions

Semantics

If the declaration of an identifier for an object has file scope
and an initializer, the declaration is an external definition for the
identifier.

A declaration of an identifier for an object that has file scope
without an initializer, and without a storage-class specifier or with
the storage-class specifier static , constitutes a tentative
definition. If a translation unit contains one or more tentative
definitions for an identifier, and the translation unit contains no
external definition for that identifier, then the behavior is exactly
as if the translation unit contains a file scope declaration of that
identifier, with the composite type as of the end of the translation
unit, with an initializer equal to 0.

If the declaration of an identifier for an object is a tentative
definition and has internal linkage, the declared type shall not be an
incomplete type.

Examples

int i1 = 1; /* definition, external linkage */
static int i2 = 2; /* definition, internal linkage */
extern int i3 = 3; /* definition, external linkage */
int i4; /* tentative definition, external linkage */
static int i5; /* tentative definition, internal linkage */

int i1; /* valid tentative definition, refers to previous */
int i2; /* $3.1.2.2 renders undefined, linkage disagreement */
int i3; /* valid tentative definition, refers to previous */
int i4; /* valid tentative definition, refers to previous */
int i5; /* $3.1.2.2 renders undefined, linkage disagreement */



extern int i1; /* refers to previous, whose linkage is external */
extern int i2; /* refers to previous, whose linkage is internal */
extern int i3; /* refers to previous, whose linkage is external */
extern int i4; /* refers to previous, whose linkage is external */
extern int i5; /* refers to previous, whose linkage is internal */
kind regards,

Jos
Jun 25 '09 #22
@JosAH
================================================== =====
>>If a translation unit contains one or more tentative
definitions for an identifier, and the translation unit contains no
external definition for that identifier, then the behavior is exactly
as if the translation unit contains a file scope declaration of that
identifier

.... the above line from your post explains my point. a "tentative definition" without an external definition is nothing but "declaration" in generic terms. so there shudn't any problem saying declaring a static variable in a header file .
Jun 25 '09 #23
donbock
2,422 Expert 2GB
My impression is that vivekbhadra and JosAH are using very different terminology; but that they both intend to describe the same practical behavior. I'm going to try to clarify ...

There is nothing magical about header files. The compiler sees absolutely no difference between these two cases:
Expand|Select|Wrap|Line Numbers
  1. header.h:
  2.     static int a;
  3.  
  4. file1.c:
  5.     #include "header.h"
  6.     ...
  7.  
  8. file2.c:
  9.     #include "header.h"
  10.     ...
and
Expand|Select|Wrap|Line Numbers
  1. file1.c:
  2.     static int a;
  3.     ...
  4.  
  5. file2.c:
  6.     static int a;
  7.     ...
The result is the two files each have their own local variable. What one file does with its variable 'a' has no effect on the other file's variable 'a'. I wouldn't call this "multiple copies of the same static variable in different files" because that suggests more of a connection between the variables than actually exists. The only same-ness is that local variables in two different source files happen to have the same identifier. This happens all the time without confusing anybody; accomplishing the same thing with a header file ought not to suddenly confuse us.

By the way, defining a static variable in a header file is not always a mistake. I have occassionally found it useful to do so. For example, a file-scope context variable accessed by each invocation of a macro (also defined in that same header). I categorize this practice as "tricky code" and comment accordingly.


and just one more information when you are talking about a header file it's always declaration not definition .... until the header file is included in a C/C++ file it never gets it's memory allocated ... so it's a declaration in a header file not definition
That is a very fine semantic distinction. The next step would be to suggest that a text file doesn't really contain C code until it is processed by a compiler. There is some merit in this existential argument, but little utility. The ability of an experienced programmer to read and interpret a block of C code is not affected by whether or not that code is ever presented to the compiler. By the way, many C compilers have command line switches that can be set to compile a .h file as if it were a .c, so to repeat myself: there is nothing magical about header files.


So the real significance of the static storage class vanishes when it's declared in a header file
I don't understand what this statement is intended to mean. Variables declared static in a header are emphatically still static when the .c file including that header is compiled -- see the code snippets at the top of this message. Perhaps the poster meant that defining static variables in a header file won't accomplish what you're trying to do. I guess that depends on what you're trying to do.
Jun 25 '09 #24
souma
1
file means?other section of same prgrm or diff prgrm?
Jul 23 '14 #25
donbock
2,422 Expert 2GB
@souma, are you referring to my reply #24? I was doing something a little tricky: each code snippet indicates the contents of separate text files: header.h, file1.c, and file2.c.

file1.c and file2.c are separate source files so each is presented separately to the C compiler. Implied in the thread is that the resulting object files are linked together into a single executable file. Presumably you intend "program" to be the same thing as "executable file".
Jul 23 '14 #26

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

2 posts views Thread by Bryan Parkoff | last post: by
4 posts views Thread by C_Programmer | last post: by
53 posts views Thread by fdmfdmfdm | last post: by
13 posts views Thread by yanlinlin82 | last post: by
37 posts views Thread by minkoo.seo | last post: by
2 posts views Thread by drmario | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by harlem98 | last post: by
reply views Thread by listenups61195 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.