What is the difference between static int a and int a? [duplicate] - c

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Difference between 'global' and 'static global'
What is the difference between statements 1 and 2 :-
#include <stdio.h>
//In the global declaration area
static int a; // 1.
int b; // 2.
Thanks for help.

A static global variable is local to the translation unit it is defined in. So, if you define static int a; in two different translation units, this will create two independent variables. If you define a non-static global variable int b; in two translation units, you will experience a linker error (but you can use extern int b; in one of the two translation units to tell the linker that it should use the global variable from the other translation unit).

Both are variable definitions, however, the static keyword applied to a variable in the "global declaration area" restricts that global variable to be seen only in the translation unit in which it is defined.

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.
Original source - http://bytes.com/topic/c/answers/860211-global-variable-static-global-variable

static int a is only accessible within that file. int b can be accessed with extern int b from a different file.

static int a;
int b;
a has internal linkage. b has extern linkage.
C99 6.2.2
6.2.2 Linkages of identifiers
1) 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.
2) 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.
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.

A static variable's life extends across the lifetime of the program. However, scope rules still apply.
If you define your static variable outside of a method (normally at the beginning of the class) your variable will be available from anywhere within that class.
You can't change the value of these objects. They're normally used for storing things like API keys.

Related

scope of static variable in c

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.

A static variable and a global variable both reside in data segment. Still, static variable has scope limited. Why?

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.

Does this invoke undefined behavior with linkage in C?

From section (6.2.2/7) C99 Standard
7. If, within a translation unit, the same identifier appears with
both internal and external linkage, the behavior is undefined.
While the following generates a compile time error due to conflict of definitions
// 'x' has external linkage
extern int x;
// Here, 'x' has internal linkage
static int x;
But the following compiles fine,
// 'x' has external linkage
extern int x;
void foo() {
// Here, 'x' has internal linkage
static int x;
}
Do both the cases invoke an undefined behavior?
Your question stems from an incorrect assumption that a locally declared static variable has internal linkage. In reality a static variable declared in a block scope has no linkage. See 6.2.2/6
6 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.
Only file-scope declaration can have external or internal linkage (plus local extern declarations).
Therefore 6.2.2/7 and your question simply do not apply.
As far as I know, it doesn't, since the two variables aren't the same. The local variable takes priority over the global one, and in the scope of foo(), it's declared only once. See the assembler output - the compiler will most likely translate the two variables into two different symbols.

what is the advantage of static function?

see in one project source code i have seen belows declaration
static int *foo();
so it declare foo as static function returning pointer to int. So here i wana ask you whats the purpose of declaring function as static ?
The function's name isn't visible outside the translation unit (source file) in which it's declared, and won't conflict with another function foo in another source file.
In general, functions should probably be declared static unless you have a specific need to call it from another source file.
(Note that it's only the name that's not visible. It can still be called from anywhere in the program via a pointer.)
It prevents other translation units (.c files) from seeing the function. Keeps things clean and tidy. A function without static is extern by default (is visible to other modules).
From the C99 standard:
6.2.2 Linkages of identifiers
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
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.
Declaring a function as static prevents other files from accessing it. In other words, it is only visible to the file it was declared in; a "local" function.
You could also relate static (function declaration keyword, not variable) in C as private in object-oriented languages.
See here for an example.
Marking a function or a global variable as static makes it invisible to the linker once the current translation unit is compiled into an object file.
In other words, it only has internal linkage within the current translation unit. When not using static or explicitly using the extern storage class specifier, the symbol has external linkage.

What's the difference between int and extern int in C?

int i; // A.
extern int i; // B.
I know A is a variable's definition. Namely, the compiler creates an object and assigns a block of memory to the variable i. But what is B? What's the difference between the definition and the declaration?
It's a declaration. It says there is an integer i that will be defined elsewhere.
Case A) is a 'tentative defintion' with external linkage. You can have multiple of these in a single translation unit, and all will refer to the same variable. The definition is called tentative because it will only zero-initialize the variable if there is no other definition with explicit initializer in the translation unit.
Case B) is a declaration but not a definition (tentative or otherwise), because there is no initializer present and no storage will be reserved. There must be a valid definition of the variable elsewhere in this or another translation unit. If there's a previous declaration of the variable with internal linkage in scope, the variable will have internal linkage, otherwise external, ie
static int foo;
extern int foo;
results in a valid tentative definition with internal linkage, whereas
extern int foo;
static int foo;
is invalid as you have a declaration with external linkage followed by a (tentative) definition with internal linkage.
See C99 sections 6.2.2 and 6.9.2 for details.
The extern keyword introduces a variable declaration, not a definition. It says that somewhere in some source file there will be a variable defined with the given declaration, which allows the source file to reference the variable without hassle, but doesn't actually define the variable. This allows one variable defined in one file to be shared and accessed across multiple source files without each file having its own independent copy.
B states that the variable i is defined elsewhere, typically in a different translation unit. The Wikipedia article would not be a bad place to continue your research.
A) As well as declaring the variable i, it is actually implicit definition of i.
B) A declaration of i. You will need the variable i to be defined some where.

Resources