I just started learning C programming.
In some of the books and web articles, I could find that any Global Variable in C by default corresponds to static storage class but has external linkage.
Does this mean it is partially static and partially extern? Because as per my understanding any global variable with static storage class specifier has internal linkage only and can be accessed within the same file.
P.S: I referred this question Global variables in C are static or not? , but could not get really whether Global variables are static or extern by default in C.
Global Variable in C by default corresponds to static storage class but has external linkage. Does this mean it is partially static and partially extern?
The English word “static” has muddled and multiple meanings in C, and, yes, the default for a variable declared outside a function is to have static storage duration and external linkage.
Because there are multiple concepts here and some mixed use of word meanings, we should clarify some terminology and formatting:
Use code style to refer to specific text in source code, such as the keyword static. When speaking of static storage duration or external linkage, “static” and “external” are mere English adjectives and should not be in code style.
“Global” means visible throughout an entire program. The C standard does not use this word for this purpose. It uses “external” to refer to things that are outside of (external to) any function. (But it also uses “external” for other purposes.) A global variable could not have internal linkage, because it would not be visible throughout the entire program.
A variable consists of an object (memory reserved for representing the value) and an identifier (the name). Storage duration is a property of the object. Linkage is a property of the identifier.
The English word “static” generally means unchanging. The C standard uses this word and the keyword static in multiple ways:
Static storage duration means the memory for an object is reserved throughout all of program execution.
Using the static keyword in a declaration, other than as below, both gives an object static storage duration and, in a declaration outside a function, gives the identifier internal linkage.
Using the static keyword inside subscript markers in a parameter declaration, as in void foo(int a[static 3]), indicates that the parameter points to at least the stated number of elements.
Static assertions, using _Static_assert, provide compile-time tests (which can help detect bugs or ensure a program is being compiled with expected settings).
These multiple uses are unfortunate and are due at least partly to the history of how the C language was developed.
Whenever you don't intend to use a variable declared in one file in a Different file the you should use static keyword before the declaration
file1.c:
static int number = 63; // this variable is used only in this file
...
file2.c:
float brightness = 0.5; // is needed in some Other file;
...
file3.c:
extern float brightness; // use external declaration to use it here
...
When ever possible, you should use the static variables.
If you want to use two global variables in two different translation units (c files) then your compiler will throw an error saying that the variable is already declared elsewhere.
Using static will make it hidden for other translation units.
You mix up static and static storage duration.
Storage duration and linkage are different terms. There is nothing in C called "global", though the term is often sloppily used for any variable declared at file scope - that is: outside any function. More correct use of the term "global" would be that the variable has external linkage, meaning it may be referred to anywhere in the whole project.
All variables declared at file scope have static storage duration. This dictates how such variables are initialized and that they persist throughout the whole exeuction of the program (practically, it likely also means that the variable ends up in .data or .bss segments of the implementation).
A variable declared at file scope but without any storage class specifier (neither static nor extern) has external linkage, but it still got static storage duration. From 6.2.4:
If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.
But if you add a storage class specifier to a file scope variable, you specify both storage duration and linkage. 6.2.4/3:
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.
And as you say, a variable with internal linkage can only be referred to from the same file (strictly speaking same "translation unit").
There's some subtle difference here in case you add static to a local variable - it then specifies storage duration but not linkage. The whole term linkage is rather confusing - simply put the purpose of the term is to dictate when two variables with the same name refer to the same object or different ones. This is mostly a concern for those making compilers/linkers as well as for spaghetti programmers. Avoid belonging to the latter category by following the advise below.
Beginners need not worry about any of the above.
Rules of thumb for beginners:
Never declare variables outside functions unless they are static.
Never declare variables in header files.
Never use extern.
Use static in front of functions if they aren't meant to be called from other files.
This will get you very far, and the rare cases where you actually need to share variables between different files is another story/advanced topic.
Related
I have read about global and local variables and static keyword, but i dont know which is the difference between something like this:
int x; //Global variable
int main(){
//Code...
}
And this:
static int x; //Static Global variable
int main(){
//Code...
}
I know some properties of the static keyword, and i know why is useful for local variables, but i dont know which is the use for global variables
I have read that using static for global variables is used for accesing the variable only in the C file it is declared/defined, but, i mean, if we dont use extern we just cant access that global variable in other c files anyway
I think that a "static global" variable is used to prevent the use of the extern keyword in order to prevent the use of that variable in multiple C files, is that correct?
Thanks in advance!
"Global" is not a formal term, but it generally means "variable that can be accessed anywhere". Therefore global.
To dive into some formal terms:
The formal and correct term for a variable declared outside a function is declared at file scope.
What formally defines how a variable may be accessed in C is referred to as linkage.
A variable declared at file scope generally has external linkage and can be referred to from elsewhere with extern.
So the correct term to use for your first example is "file scope variable with external linkage".
Whenever we add the storage class specifier static to a declaration, we force the variable or function to instead get internal linkage. This means that it is only accessible from within the translation unit (the .c file and all .h files it includes) where it was declared.
It is the opposite of global, so saying "static global" doesn't make any sense. You cannot refer to such a variable with extern. Instead the correct term is "file scope variable with internal linkage".
The main purpose of static is indeed private encapsulation, since the internal linkage guarantees that the variable or function cannot be accessed by other .c files.
But static also at the same time gives static storage duration to a variable, meaning it is guaranteed to persist throughout the execution of the program and that it has some initialization rules guaranteed. Now as it happens, variables at file scope always gets static storage duration, static or not, so it isn't very relevant to your example. But as you earlier discovered, static storage duration does make a big difference for local variables, since their value will then be preserved throughout multiple function calls.
More details here: What does the static keyword do in C?
Yes, it is correct.
A global static variable can only be accessed in the file where it is created (file scope).
I'm reading k&r book. In section 4.6,it says: The static declarations, applied to an external variables or functions , limits the scope of that object to the rest of the source file being compiled. I'm confused with the scope of static external variables when written with extern keyword in different source files.
Any identifier declared outside a function has file scope. The declaration is only visible inside the current translation unit, which is one source file along with all files included via the #include preprocessing directive.
By default, identifiers for objects declared at file scope have external linkage. This means that, if the same identifier is declared in separate translation units, it refers to the same object. (An object is a region of storage that can represent a value. What you think of as a variable is a combination of its name, the identifier, and the memory used for it, the object.)
When a declaration for an object includes static, the identifier has internal linkage. This means that other declarations inside the same translation unit with internal linkage will refer to the same object, but declarations in another translation unit will not refer to the same object.
Note that, for historic reasons, there are multiple meanings and effects associated with static and external. All declarations outside of functions (including declarations of functions) are external declarations in the language of the C standard, even if they include static. In this usage, “external” means outside a function. In regard to the phrase external linkage, “external” refers to linkage outside the translation unit. In declarations, the keyword static can affect both linkage (changing it from a default of external when outside a function or from no linkage when inside a function) and also storage duration (changing it from a default of automatic inside a function to static storage duration). One might also say that definition int a[5] is a static definition in the sense that the array size is fixed. Unfortunately, we are simply stuck with these multiple effects and meanings, and you will have to learn them.
I know what static classes are I would like to know more about the word "static".
When I search for the word "static" I get many definitions, from most of them I get that static is something that doesn't move (fixed in place). Is it right?
What does the word mean? Where did the word came from historically?
Thank you in advance.
Static is a keyword used to give special characteristics to an element. Static elements are allocated storage only once in a program lifetime in static storage area. And they have a scope till the program lifetime. Static Keyword can be used with following, Static variable in functions.
In the C programming language (and its close descendants such as C++ and Objective-C), static is a reserved word controlling both lifetime (as a static variable) and visibility (depending on linkage). The word static is also used in languages influenced by C, such as Java.
In C, static is a storage class (not to be confused with classes in object-oriented programming), as are extern, auto and register (which are also reserved words). Every variable and function has one of these storage classes; if a declaration does not specify the storage class, a context-dependent default is used:
extern for all top-level declarations in a source file,
auto for variables declared in function bodies.
Storage class Lifetime Visibility
extern program execution external (whole program)
static program execution internal (translation unit only)
auto, register function execution (none)
In these languages, the term "static variable" has two meanings which are easy to confuse:
A variable with the same lifetime as the program, as described above (language-independent); or
(C-family-specific) A variable declared with storage class static.
Variables with storage class extern, which include variables declared at top level without an explicit storage class, are static in the first meaning but not the second.
The static keyword when prefixed while declaring a variable or a function can have other effects depending on where the declaration occurs.
Static global variable
A variable declared as static at the top level of a source file (outside any function definitions) is only visible throughout that file ("file scope", also known as "internal linkage").
Static local variables
Variables declared as static inside a function are statically allocated, thus keep their memory cell throughout all program execution, while having the same scope of visibility as automatic local variables (auto and register), meaning remain local to the function. Hence whatever values the function puts into its static local variables during one call will still be present when the function is called again.
Static member variables
Member variables declared as static inside class definitions are class variables (shared between all class instances, as opposed to instance variables).
Static function
Similarly, a static function -- a function declared as static at the top level of a source file (outside any class definitions) -- is only visible throughout that file ("file scope", also known as "internal linkage").
Static method
Similarly, a static method -- a method declared as static inside a class definition -- are meant to be relevant to all instances of a class rather than any specific instance.
In a typical C program, both static variable and global variable reside on the data segment. Still the scope of static variable is limited to file. On the contrary, the global variable can be accessed from anywhere. Why does it happen, although both reside in the same memory?
By design.
static at global scope is the keyword you use to mean "I want these variables limited in scope; I do not want to have to care what other modules have declared variables of the same name." The reason using this keyword does a different thing to not using it is in fact exactly the reason for its existence.
Note the keyword means different things in different contexts; at function scope static means "the contents of this variable should persist between function calls".
The actual arrangement of data in memory that results is an implementation detail, and will vary between compilers and platforms.
Why does it happen, although both resides in the same memory?
Short answer:-
From the C11 standard ( 6.2.2 Linkages of identifiers) para 4 :
If the declaration of a file scope identifier for an object or a
function contains the storageclass specifier static, the identifier
has internal linkage.
Internal linkage means that its visible only inside its translational unit.
Detailed answer:
A global variable(without static) has external linkage which means it is visible to other translational units.
When you declare static variables with file scope it has internal linkage but when you declare it with block scope it has no linkage.
Lets understand few terms specifically .( inspired from C keywords (static))
A C variable has one of the following linkages:
no linkage :- Variables with block scope have no linkage.It means they are private to the block in which they are defined . All variables with automatic, thread and dynamic storage durations have this linkage, as well as variables declared static at block scope.
A variable with file scope can have either internal or external linkage.
internal linkage :- The variable can be referred to from all scopes in the current translation unit. All variables which are declared at file scope have this linkage, including variables declared static at file scope.
external linkage :- The variable can be referred to from any other translation units in the entire program. All variables which are declared either extern or const with no explicit storage-class specifier, but not static, have this linkage.
e.g-
int i = 5; // file scope, external linkage
static int j = 3; // file scope, internal linkage
...
...
int main()
{
...
...
}
int func ()
{
static int num;// block scope – no linkage
. . .
}
By declaring a variable static on file level (static within function has a different meaning) you forbid other units to access it, e.g. if you try to use the variable inside another unit (declared with extern), linker won't find this symbol.
Emphasis mine :)
The idea of static variables is that they're not global and don't 'pollute' the global namespace. It means I can use the variable 'count' in 5 different functions and they won't clash. Scope confines variables to their context.
Technically you can access anything. The compiler just wouldn't give you a memory address - you would have to get it yourself. Somehow.
I know there are three types of static declerations in C:
1: Constant - constant static variable, ex: static const int i = 5;
2: Changable - just a normal static variable, ex: static int hi = 10;
Here is my question
There is another form of static which takes the form of "code". What does that mean and can you give me an example?
Thank you!
EDIT:
Are static/const variables stored on the stack/heap?
Maybe you are talking about a static function ?
This is a specific use of the word "static", which is entirely different from a static variable.
When you declare a function "static", that means it cannot be linked from another source file. It is typically used to keep some functions "private".
[Edit] Note that, in theory, the function code could still be accessed from another source file using pointers, but that's not quite the normal way (and certainly not the easiest) to access a function. Thanks to Eric Postpischil for pointing that out.
It's unfortunate that the same word "static" is used in the C standard to mean two different things, depending on being used for functions or variables.
[edit] : It's a different question, but anyway : in the case of static variables, they are neither allocated in the heap nor the stack. They are, well, static, which means they are allocated in a static space, directly allocated by the compiler at startup. Stack is for internal functions variables, and heap is for malloc()/free().
This link should answer your question.
It is however worth noting that unless you have sufficient knowledge of the C compilation process this will be of questionable value.
A good reference for GCC can be found here.
I believable you're asking about static functions.. So..
Static functions
By default, functions in C are extern, meaning that the function can be used in any other file of the same project (and the same code of course).
If you don't like this situation and you want to limit the function to the file in which it's defined, you make it static.
The keyword static is used in several different ways in C. (There's a joke that any new version of the ISO C standard is required to invent a new meaning for static.)
Quick summary: The static keyword on a block scope definition gives the entity static storage duration; at file scope, where definitions already have static storage duration, it instead gives them internal linkage.
An object may have any of several storage durations. An object with "automatic" storage duration exists at run time only during the execution of the enclosing block. An object with "static" storage duration exists during the entire execution of the program. (There are also "allocated" and, new in C11, "temporary" storage durations, which I won't get into.)
Any definition of an identifier also has a "linkage", which can be external, internal, or none. Linkage controls whether an identifier is usable across translation units (basically source files, but #included files are not separate translation units). Linkage, as the name implies, has to do with the linker. You can use the same identifier with internal linkage in two different source files, and it will refer to two different entities. But if an identifier has external linkage, it should be defined only once, and can be declared (typically with extern) in multiple source files; all those declarations will refer to the same entity.
If you define an object (variable) at block scope, (i.e., inside a function body), it has automatic storage duration (and no linkage) by default. Adding the keyword static gives it static storage duration, so it exists and retains its value across calls to the function. (It doesn't affect the identifier's visibility).
If you define an object at file scope (i.e., outside any function body), it has static storage duration and external linkage by default. Adding the keyword static to the definition doesn't affect its storage duration, but it changes its linkage from external to internal, hiding the name from other translation units. Functions don't have storage duration (their code exists as long as the program is running), but static affects their linkage the same way, changing it from external to internal.
(C99 added another meaning for static, for function parameters of array type, which has nothing to do with the other uses.)
I think it's worth to clarify what we're talking about and try to use the correct wording.
The const qualifier has nothing to do with the static keyword.
Technically, the static keyword appears in declarations and it's usually a storage-class specifier, but from C99 it can also be in array declarators, though this is quite unusual.
When it's a storage-class specifier, just like in the declarations you've posted, it affects the linkage (visibility between files) of the identifier and the storage duration (lifetime) of the identified object, but not the scope of the identifier.
6.2.2 Linkages of identifiers
[...] Within one translation unit, each declaration of an identifier with internal linkage denotes the same object or function. [...]
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.30)
30) A function declaration can contain the storage-class specifier static only if it is at file scope; see 6.7.1.
Therefore, the identifier can only be seen in the translation unit (i.e., a source file after the preprocessing) where it's declared, whether it's an object or a function (maybe that's what you were looking for). So you can use to declare "private" functions to be used in just one file.
static void foo(void)
{
// ...
}
The static keyword it's also used with the inline function specifier, which has a particular linkage semantics: https://stackoverflow.com/a/216546/1202636
Obviusly when we are not at file scope but in a more restricted one (static declarations inside functions) the linkage question becomes irrelevant since such an identifier has no linkage at all.
6.2.4 Storage durations of objects
An object whose identifier is declared [...] either 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.
This one only applies to object identifiers and it affects the lifetime of the object, for example letting a variable retains its value between calls, and its initialization.
(just to say it, such an object is also initialized with a default value)
As I said, there's a less common use of the static keyword: it can be use in array declarators inside function prototypes, to tell the compiler that an array given as parameter contains at least n elements. This is a (modified) example from the standard:
void f(double a[static 3][5]);
The declaration specifies that the argument corresponding to a in any call to f must be a non-null pointer to the first of at least three arrays of 5 doubles, which the others do not.
.
Are static/const variables stored on the stack/heap?
Again, the constness has nothing to do with the place where an object is stored. The standard doesn't say anything about that place, there's usually a dedicated area but this is a different and already answered question: where are static buffers allocated?
Are static/const variables stored on the stack/heap?
Well, no, they are part of the "global" space.
Stack and Heap are for "dynamic" memory allocation, not static !