What local variables retain their value between function calls?

The scope of a variable is the portion of the program where the variable is valid or "known".

Local Variables

  • ★ A local variable is defined inside a function or a block statement and is not accessible outside the function or block.
  • ★ This means that these variables are visible and can only be used by the function in which the variable is defined!
  • Local variable lifetime: A function's local variables exists only while the function is executing.
  • ★ When the function begins, its local variables and its parameter variables are created in memory, and when the function ends, the local variables and parameter variables are destroyed.

What is the output of the following code fragment?

void  ThisFunc[int];

int main[]
{
  int  m1,  m2;
  m1 = 1;
  m2 = 21;
  ThisFunc[m2];
  cout  40 ] {
        
            char x[ 'A' ]; // Very local, value = 65
            
            printf[ "Third x = %c\n", x ]; // Prints very local, 'A'
            
            func[ x ]; // Passes the very local char, converted to an int.
            
        }
        printf[ "Fifth  x = %d\n", x ]; // Ordinary local 42 again
        
        return 0;
    }
    
    void func[ int x ] { // local parameter
    
    	printf[ "Fourth x = %d\n", x ]; // Local parameter, 65
        
        return;
    }

    Program Output:

    First x = 0.0
    Second x = 42
    Third x = A
    Fourth x = 65
    Fifth x = 42

Storage Class

  • Variables can be in one of four storage classes, depending on where in computer memory they are stored.

    Automatic Variables

    • Automatic variables, [ a.k.a. auto variables ] are stored on a data structure known as "the stack".
    • The stack grows and shrinks as a program executes.
    • In particular, when a new function is entered, space is allocated on the stack to store all of the local variables for that function. [ Actually space is allocated for each variable at the time when it first goes into scope, i.e. when it is declared. ]
    • More importantly, when the function exits, the stack space allocated to that function is freed up, and becomes available for other uses. [ The stack shrinks. ]
    • Local variables, function parameters, and very local variables are ordinarily auto variables stored on the stack.
    • Any data stored in auto variables is lost when the variables go out of scope, i.e. when a function exits. The next time the variable comes back into scope [ i.e. when the function gets called again ], the variable is allocated new space, and re-initialized if an initialization is given.

    Static Variables

    • Static variables are stored in a separate storage area known as "the heap".
    • Space for static variables is allocated one time only, before main[ ] begins, and never expires.
    • Global variables are normally static. Other variables may be declared static.
    • In particular, if function variables are declared as "static", then they are only initialized once, and retain their values between function calls. [ The variables can still go out of scope, but when they come back into scope they will still retain their previous values. ]
    • Example: The following code will generate the output shown below the code:
  •             void staticExampleFunction[ void ];
                
                int main[ void ] {
                
                    for[ int i = 0; i < 5; i++ ]
                    	staticExampleFunction[ ];
                        
                    return 0;
                    
                } // main
                
                void staticExampleFunction[ void ] {
                
                    int normalInt = 0;
                    static int staticInt = 0;
                    
                    printf[ "The normal int = %d.  The static int = %d.\n", ++normalInt, ++staticInt ];
                    
                    return;
                }

    Output:

                The normal int = 1.  The static int = 1.
                The normal int = 1.  The static int = 2.
                The normal int = 1.  The static int = 3.
                The normal int = 1.  The static int = 4.
                The normal int = 1.  The static int = 5.
    • Static variables can be used to count how many times a function is called, or to perform some special behavior the first time a function is called. [ Declare a static variable "firstTime" initialized to true. If firstTime is true, do the special code and then set firstTime to false. ]
    • Variation: The static keyword applied to a global variable makes it global to this file only, and not visible from other files, [ in a multi-file development project. ]

Extern Variables

  • The "extern" keyword applied to a variable indicates that it is declared and allocated space in some other file.
  • A declaration with the word "extern" is like a function prototype - It tells the compiler of the existence of the variable, without actually creating it or allocating any space for it.
  • All such variables must be declared exactly once, [ i.e. in one file only of a multi-file development project ] without the "extern", so that space can be allocated for it.
  • Exterm variables are global in the file in which they are declared without "extern", but may be either local or global in other files.
  • Extern will be covered more fully under the topic of multi-file development.

Register Variables

  • The keyword "register" suggests to the compiler that the given variable be stored in one of the CPU registers, [ for faster access ], instead of in regular memory.
  • Register variables act as auto variables, except they do not have an "address", and so cannot be referred to by pointer variables or by the address operator, &.
  • Loop counters are the most common and obvious use of register variables.
  • Modern optimizing compilers have elminated most need for the keyword register.

Summary of Variable and Parameter Declaration Qualifiers

The following example shows all possible qualifiers for variables and function parameters, and how those qualifiers affect the variables in three key areas:

  1. Storage duration, indicating whether the item continues to exist when it goes out of scope [ static storage ], or whether it is re-created and re-initialized every time that it goes into scope [ auto storage. ]
  2. Scope, indicating whether the item is available to the remainder of the file [ file scope ], or only through the remainder of the block in which it is defined [ block scope. ]
  3. Linkage, indicating whether the item is also accessible from other files [ external linkage ] or whether it is private to multiple functions only within this file [ internal linkage ], or whether it is accessible only within a block [ no linkage, i.e. none. ]
        int a;
        extern int b;
        static int c;
        
        void f[ int d, register int e ] {
        	auto int g;
            int h;
            static int i;
            extern int j;
            register int k;
        }
NameStorage DurationScopeLinkage

a

static

file

external

b

static

file

??? - see below

c

static

file

internal

d

auto

block

none

e

auto

block

none

f

auto

block

none

g

auto

block

none

h

auto

block

none

i

static

block

none

j

static

block

??? - see below

k

auto

block

none

??? - The linkage for b and j depends on their original declaration, but are normally external

Inline Functions [ C99 only ]

There is also one additional qualifier that can be applied to functions only: inline

The ordinary function call-and-return mechanism involves a certain amount of overhead, to save the state of the original function on the stack, create stack space for a return address and the local [ auto ] variables needed for the new function and its parameters, transfer control to the new function, do the work, store the return value back on the stack, clean up the stack, and then transfer control back to the original calling function.

For certain small fast functions, this overhead can add significantly to the processing time of the function, often greatly surpassing the effort needed to perform the work of the function.

Therefore the inline qualifier applied to a function suggests to the compiler to simply copy the instructions for the function into this location in the calling function's code, instead of invoking all of the overhead of the call and return process.

An alternative to inlined functions is parameterized macros, implemented with #define, which are covered elsewhere.

Related Topics

The following topics are not covered here, but may be found in many books on C Programming

  • Functions with variable argument lists [. . . ]

Which type of local variables can retain their values between function calls?

static local variables retain their contents between function calls. static local variables are defined and initialized only the first time the function is executed.

Which variable retains its value in between function cells?

varN as persistent. Persistent variables are local to the function in which they are declared, yet their values are retained in memory between calls to the function.

Is it possible for local variables to maintain its data between function calls?

For example, if you are using the Small memory model and you declare a local variable to be in pdata or xdata, the variable retains its value between function calls. However, this may change in future versions of the Compiler and must not be relied upon.

What kind of variables are local variables in a function?

In computer science, a local variable is a variable that is given local scope. A local variable reference in the function or block in which it is declared overrides the same variable name in the larger scope.

What happens to a local variable when a function call completes?

When the execution of the function terminates [returns], the local variables are destroyed. Codelens helps you visualize this because the local variables disappear after the function returns.

What are the variables used in function call?

The term parameter [sometimes called formal parameter] is often used to refer to the variable as found in the function definition, while argument [sometimes called actual parameter] refers to the actual input supplied at function call.

Chủ Đề