CSE 2421
CSE 2421
C Storage Class, Scope, and Linkage
Required Reading: Pointers On C, Chapter 3, Sections 3.5 through 3.10 with a special interest in Table 3.4.
When programming in any language, it is usually important to know what type of memory holds your data
Stack
Heap
Disk
Storage class: 4 types (only 3 really)
static
automatic (or auto)
register
external (not really storage class, but linkage)
THIS CLASS HAS NO RELATIONAHIP WITH CLASSES IN C++
Storage Scope: 4 types (we will only cover 3)
block
file
prototype
function (very limited use (only labels for goto); we will not cover this)
Storage Linkage: 3 types
internal
external
none (no linkage)
CAUTION: Learn the terms! “Global” and “Local” are not correct terms for storage class, scope, or linkage in C!
Overview of concepts and terms
Storage class: determines (a) the type of storage and the lifetime of the storage associated with a variable, and (b) the variable’s initialization.
Storage Scope: determines the region of a program in which a variable can be accessed directly (i.e., by name, and not through a pointer).
Linkage: for a given name (identifier), linkage determines whether the same name in a different scope refers to the same variable or function, or some different variable or function [e.g. You have someone in 3 of your classes named Noah. Is it the same person or 3 different people all named Noah?]
Terms/Concepts – introduction
A Process can be defined as a group of functions that work together to perform a particular job. (e.g. main(), other functions written by the software developer and C library functions.
Stack
A place in memory where information specific to a particular function is stored each time it is invoked.
It is allocated when the function is called and deallocated when the function returns.
When a function stops executing or returns, any variable declared and stored on the stack is no longer available.
Essential for recursive function calls.
Heap
A place in memory where information specific to a particular process is stored each time it is invoked.
Any values stored here are available until the process stops executing.
Where calloc() and malloc() memory addresses are.
Essential for values that must be persistent within a process no matter what function is currently executing.
Storage Locations
Refers to the type of memory in which the variable’s value is stored, which in turn defines different characteristics for the variable
static (keyword) – The heap
auto (keyword) – The runtime stack
register (keyword) – Hardware registers
Determines when the variable is created and destroyed and how long it will retain its value. Note this information on the following slides.
Determines whether the variable will be initialized by the compiler (the loader actually) or whether it must be done explicitly by the program code
The default storage class for a variable depends on where it is declared (see following slides for different possible places in a C program)
6
Storage Class
https://www.tutorialspoint.com/cprogramming/c_storage_classes.htm(look here for examples)
6
Declared outside any/all blocks
Storage class is static (stored on the heap)
No way to specify any other
storage class for these variables
These variables are created before the
program begins to run (or dynamically
at runtime – more later) and exist throughout
its entire program execution.
These variables are initialized by default (by the
loader) to a zero value appropriate to their
declared type
They retain last value they were assigned until the program completes (i.e., the values are retained from the completion of one function to the beginning of the next function)
Can be declared above all functions in the program, but can also be declared between two functions (this affects scope, though; see below)
7
Storage Classes – Static
#include
int main() {
…….
}
Declared within a block
Storage class default is automatic (stored
on the runtime stack)
Created just before execution of any code in the block in which they are declared
“Discarded” (technically, we should say “inaccessible”) just as execution leaves that block
These variables must be explicitly initialized by your code, or they will contain garbage (unknown/unpredictable values)
New copies created each time the block is executed, so values are not retained in between each of multiple executions of the code in the block (for example, between function calls).
Parameters passed to functions have automatic storage class also (to support recursion), and there is no way to change this (see below)
Storage Classes – Automatic
#include
int main() {
…….
}
Variables declared within a block but with the keyword static change storage class from automatic (the default) to static
This changes where the variable is stored from the stack to the heap
Static storage class exists for the entire duration of the program, rather than just the duration of the block in which the variable is declared
NOTE: changing of the storage class of a variable does not change its scope (see below); it is still accessible by name only from within the block
NOTE: parameters to a function cannot be declared static, because arguments are always passed on the stack to support recursion. Thus, the keyword static cannot be used with parameters.
9
Storage Classes – static
When used in declarations of variables that appear outside of blocks, or in function definitions (i.e., the function is designated as static)
The keyword static changes the linkage from external to internal
The storage class and scope are not affected.
Thus, this is really a distinct use of the keyword static in C, because it relates to linkage, and not to storage class (although historically, it was referred to as storage class)!
Accessible only from within the source file in which they were declared
This is used to limit the accessibility of “global” variables (variables declared outside any block) in library functions (so that, if you happen to use a global variable in your program with the same name as a global in the library function, you will not get unexpected results).
10
Storage Classes – static (cont)
So,
When the keyword static is used within a block, it changes a variable’s class
When the keyword static is used outside of any/all blocks is changes a variable’s linkage
11
Storage Classes – static (cont)
Can be used on automatic variables only to indicate that they should be stored in the machine’s hardware registers rather than in memory.
WHY? To be accessed faster
NOTE – the compiler can ignore this if necessary; i.e., if too many variables designated as register (first come, first served) rest are automatic
Typically declare heavily used variables as register variables (i.e., loop indices)
Created and destroyed at the same time as automatic variables
12
Storage classes – register
Automatic
Default storage class for variables declared inside blocks
Discarded on exit from block
Can have auto specifier – but it is redundant (it’s the default)
Can have register specifier
Stored in fast registers of the machine if possible instead of RAM
Static
Default storage class for variables declared outside of any block
Declared outside function blocks
Can also be declared within a function with keyword static
Initialized at load time and retains its value between calls to function
Initial value must be a constant known at compile time
13
Storage Class Summary
13
The area in the program in which an identifier may be used to access a variable directly (i.e., not through a pointer)
We’ve already briefly discussed variables with file scope
For example, the scope of the variables declared inside a block in a function is limited to that block in that function
This means:
No other function may access these variables by their identifier names because the names cannot validly refer to these variables outside of their scope
It is legal to declare different variables with the same names so long as they are not declared in the same scope.
Scope types:
block
file
prototype
function (only relevant to labels with goto – we will not cover this)
Where a variable (identifier) is declared determines its scope
14
Scope
A block is a list of statements enclosed in braces
Any identifiers declared at the beginning of the block (where they must be in ANSI C89/C90) are accessible to all statements in the block
The formal parameters of a function definition also have block scope in the function’s body
Local variables declared in the outermost block cannot have the same name as any of the parameters because they are all declared in the same scope
Nested blocks having declarations of variables with the same name
The outer block variable cannot be referenced by name from within the inner block, because they are hidden by the variable declared in the inner block (DO NOT DO THIS, because it decreases program readability, and is error-prone)
15
Block scope
Any identifier declared outside of all blocks
Means that the identifier may be accessed anywhere from the end of its declaration to the end of the source file in which it was declared
16
File scope
Applies to variable (parameter) names given in a function prototype (declaration)
It does not apply to the function name in a prototype statement, only the parameters specified.
Remember it’s not required to supply names (only types are required)
Prototype scope extends uniquely to each prototype (the prototype scope of one prototype is different from that of every other prototype)
/* Valid prototypes */
void function1(int var1, int var2);
var1 and var2 have prototype scope, no memory is allocated for these variables at this time
void function2(int var3, int var4);
var3 and var4 have prototype scope, no memory is allocated for these variables at this time
Prototype Scope
int a;
int b (int c);
int func_d (int e)
{
int f;
…
{
int f, g, i;
…
}
{
int i;
…
}
}
In-Class Exercise – Scope
1 -> int a;
2 -> int b 3-> int c
4 -> int func_d 5-> int e
6 -> int f
7 -> int f, g, i
8 -> int i
Make a list for each type of scope (file, block, and prototype), and place each of the 1-8 in the correct list.
int a;
int b (int c);
int func_d (int e)
{
int f;
…
{
int f, g, i;
…
}
{
int i;
…
}
}
In-Class Exercise – Scope
1 -> int a;
2 -> int b 3-> int c
4 -> int func_d 5-> int e
6 -> int f
7 -> int f, g, i
8 -> int i
File scope: 1, 2, 4
Prototype scope: 3
Block scope: 5, 6, 7, 8
Linkage determines how multiple occurrences of an identifier in different scopes are treated
The scope of a variable named by an identifier is related to its linkage, but the two properties are not the same:
scope is the part of a program in a given source file where a variable can be accessed by its name, but
linkage relates to whether occurrences of the same identifier in two different source files refer to the same variable, or different variables. For that reason, linkage only relates to file scope variables and functions.
20
Linkage Types
3 types of linkage
None (no linkage)
Identifiers that have no linkage (variables without file scope) are always individuals; i.e. multiple declarations using the same identifier are always treated as separate and distinct entities. All block scope variables and parameters in function prototypes have no linkage.
Internal linkage
All references to the identifier within one source file refer to a single variable (the one declared in that source file), but declarations of, and references to, the same identifier in other source files refer to different variables
External linkage
All references to an identifier in any source file refer to the same entity
Variable known to all functions in the program; declared outside any function.
21
Linkage Types
After the individual source files comprising a program are compiled, the object files are linked together with functions from one or more libraries to form the executable program
22
Linkage
Write two functions (func_A and func_B), which return void, and have no parameters, and that have variables with the storage class, scopes, and linkage shown in the table below.
All initializations must be made in the declarations themselves, not by any executable statements in the functions.
23
Storage Class, Scope, Linkage
In Class Exercise
Name Type Storage Linkage Scope Initial Value
a int static internal accessible to func_A but not func_B 21
b char static external accessible to func_A and func_B 103
c int automatic none accessible only in func_A 42
d float static none accessible only in func_B 6.7
Solution
char b = 103;
void func_B( void ) {
static float d = 6.7;
}
static int a = 21;
void func_A( void ){
int c = 42;
}
Name Type Storage Linkage Scope Initial Value
a int static internal accessible to func_A but not func_B 21
b char static external accessible to func_A and func_B 103
c int automatic none accessible only in func_A 42
d float static none accessible only in func_B 6.7
/docProps/thumbnail.jpeg