Monday, 25 February 2013

Storage Classes


Storage Classes


static

static is sometimes a useful keyword. It is a common misbelief that the only purpose is to make a variable stay in memory.
When you declare a function or global variable as static it will become internal. You cannot access the function or variable through the extern (see below) keyword from other files in your project.
When you declare a local variable as static, it is created just like any other variable. However, when the variable goes out of scope (i.e. the block it was local to is finished) the variable stays in memory, retaining its value. The variable stays in memory until the program ends. While this behaviour resembles that of global variables, static variables still obey scope rules and therefore cannot be accessed outside of their scope.
Variables declared static are initialized to zero (or for pointers, NULL) by default.
You can use static in (at least) two different ways. Consider this code, and imagine it is in a file called jfile.c:

#include <stdio.h>
 
static int j = 0;
 
void up(void)
{
   /* k is set to 0 when the program starts. The line is then "ignored"
    * for the rest of the program (i.e. k is not set to 0 every time up()
    * is called)
    */
   static int k = 0;
   j++;
   k++;
   printf("up() called.   k= %2d, j= %2d\n", k , j);
}
 
void down(void)
{
   static int k = 0;
   j--;
   k--;
   printf("down() called. k= %2d, j= %2d\n", k , j);
}
 
int main(void)
{
   int i;
 
   /* call the up function 3 times, then the down function 2 times */
   for (i= 0; i < 3; i++)
      up();
   for (i= 0; i < 2; i++)
      down();
 
   return 0;
}
The j var is accessible by both up and down and retains its value. The k vars also retain their value, but they are two different variables, one in each of their scopes. Static vars are a good way to implement encapsulation, a term from the object-oriented way of thinking that effectively means not allowing changes to be made to a variable except through function calls.
Running the program above will produce the following output:
up() called.   k=  1, j=  1
up() called.   k=  2, j=  2
up() called.   k=  3, j=  3
down() called. k= -1, j=  2
down() called. k= -2, j=  1
Features of static variables :
    1. Keyword used        - static
    2. Storage             - Memory
    3. Default value       - Zero
    4. Scope               - Local to the block in which it is declared
    5. Lifetime            - Value persists between different function calls
    6. Keyword optionality - Mandatory to use the keyword

extern

extern is used when a file needs to access a variable in another file that it may not have #included directly. Therefore, extern does not actually carve out space for a new variable, it just provides the compiler with sufficient information to access the remote variable.
Features of external variable :
    1. Keyword used        - extern
    2. Storage             - Memory
    3. Default value       - Zero
    4. Scope               - Global (all over the program)
    5. Lifetime            - Value persists till the program's execution comes to an end
    6. Keyword optionality - Optional if declared outside all the functions

volatile

volatile is a special type modifier which informs the compiler that the value of the variable may be changed by external entities other than the program itself. This is necessary for certain programs compiled with optimizations – if a variable were not defined volatile then the compiler may assume that certain operations involving the variable are safe to optimize away when in fact they aren't. volatile is particularly relevant when working with embedded systems (where a program may not have complete control of a variable) and multi-threaded applications.

auto

auto is a modifier which specifies an "automatic" variable that is automatically created when in scope and destroyed when out of scope. If you think this sounds like pretty much what you've been doing all along when you declare a variable, you're right: all declared items within a block are implicitly "automatic". For this reason, the auto keyword is more like the answer to a trivia question than a useful modifier, and there are lots of very competent programmers that are unaware of its existence.
Features of automatic variables :
    1. Keyword used        - auto
    2. Storage             - Memory
    3. Default value       - Garbage value (random value)
    4. Scope               - Local to the block in which it is defined
    5. Lifetime            - Value persists till the control remains within the block
    6. Keyword optionality - Optional

register

register is a hint to the compiler to attempt to optimize the storage of the given variable by storing it in a register of the computer's CPU when the program is run. Most optimizing compilers do this anyway, so use of this keyword is often unnecessary. In fact, ANSI C states that a compiler can ignore this keyword if it so desires – and many do. Microsoft Visual C++ is an example of an implementation that completely ignores the register keyword.
Features of register variables :
    1. Keyword used        - register
    2. Storage             - CPU registers (values can be retrieved faster than from memory)
    3. Default value       - Garbage value
    4. Scope               - Local to the block in which it is defined
    5. Lifetime            - Value persists till the control remains within the block
    6. Keyword optionality - Mandatory to use the keyword

  • A variable declared within a block has block scope. Such a variable is also called a local variable and is only visible within the block
  • The goto label has function scope, which means that it is visible through the whole block of the function within which the label is placed. No two goto labels share the same name within a function block.
  • A variable declared with the static specifier outside a function has file scope, which means that it is visible throughout the entire source file in which the variable is declared.
  • A variable declared outside a function is said to have program scope. Such a variable is also called a global variable. A global variable is visible in all source files that make up an executable program.
  • A variable with block scope has the most limited visibility. On the other hand, a variable with program block is the most visible through all files, functions, and other blocks that make up the program.
  • The storage class of a variable refers to the combination of its spatial and temporal regions (that is, its scope and duration.)
  • By default, a variable with block scope has an auto duration, and its memory storage is temporary.
  • A variable declared with the static specifier has permanent memory storage, even though the function in which the variable is declared has been called and the function scope has exited.
  • A variable declared with the register specifier may be stored in a register to speed up the performance of a program; however, the compiler can ignore the specifier if there is no register available or if some other restrictions have to apply.
  • You can also allude to a global variable defined elsewhere by using the extern specifier from the current source file.
  • To make sure the value saved by a variable cannot be changed, you can declare the variable with the const modifier.
  • If you want to let the compiler know that the value of a variable can be changed without an explicit assignment statement, declare the variable with the volatile modifier so that the compiler will turn off optimizations on expressions involving the variable.
In the next lesson you'll learn about function declarations and prototypes in C.

Q&A

Q Can a global variable be hidden by a local variable with block scope?
A Yes. If a local variable shares the same name with a global variable, the global
variable can be hidden by the local variable for the scope of the block within which the local variable is defined with block scope. However, outside the block, the local variable cannot be seen, but the global variable becomes visible again.
Q Why do you need the static specifier?
A In many cases, the value of a variable is needed, even if the scope of the block, in which the variable is declared, has exited. By default, a variable with block scope has a temporary memory storage—that is, the lifetime of the variable starts when the block is executed and the variable is declared, and ends when the execution is finished. Therefore, to declare a variable with permanent duration, you have to use the static specifier to indicate to the compiler that the memory location of the variable and the value stored in the memory location should be retained after the execution of the block.
Q Does using the register specifier guarantee to improve the performance of a program?
A Not really. Declaring a variable with the register specifier only suggests to the compiler that the variable be stored in a register. But there is no guarantee that the variable will be stored in a register. The compiler can ignore the request based on the availability of registers or other restrictions.
Q When you declare a variable with the extern specifier, do you define the variable or allude to a global variable elsewhere?
A When a variable is declared with the extern specifier, the compiler considers the declaration of the variable as an allusion rather than a definition. The compiler will therefore look somewhere else to find a global variable to which the variable with extern alludes.

No comments:

Post a Comment