Register and volatile in C programs

December 15th, 2009 by Kevin | No Comments | Filed in C Programming

Register variables

We can specify any variable as a register variable in a C program. What this does is it specifies to the compiler that we will be using this variable heavily in our program and if possible to place that variable in a register of the CPU. If done this will significantly increase the speed of your program.

register int x;
register float y;

You can declare as many variables as you want as register variables. However the catch is that it is entirely up to the compiler whether to accept your request or not. Another point is that you cannot access the address of any register variable.

Note that it is a good idea to place variables which are counters like “i” in for(i=0; i<1000; i++).

Volatile variables

By indicating that a variable is volatile, we inform the compiler that the value of that variable can change at any time and so it should not apply optimization techniques on it. This can be explained for memory mapped peripherals.

It is quite common to map a peripheral register to memory and then access it via a C program. Suppose you have a program which reads from a hardware register the status of a particular hardware. Say you want to know whether the red LED is turned on or off.

main()
{
   int *ptr_red_led = &0x1234;
   int led_status;

   led_status = *ptr_red_led;
   led_status = *ptr_red_led; 

}

What happens in this case if compiler optimization is enabled, is that the compiler sees the two lines and feels that they are the same without any change in *ptr_red_led and so it is sufficient to use just one statement. This is wrong and it will produce wrong output as the value in *ptr_red_led can change anytime the hardware changes it’s status.

The correct way is to use the “volatile” keyword for the led_status variable as

main()
{
   int *ptr_red_led = &0x1234;
   volatile int led_status;

   led_status = *ptr_red_led;
   led_status = *ptr_red_led;    /* checking again */
}
 

Related Posts:

Tags: ,

Static variables and functions

December 14th, 2009 by Kevin | 2 Comments | Filed in C Programming

A static variable is a global variable with it’s scope limited to the function it is declared in. The keyword “static” is used to declare a static variable or function. What this means is a variable declared as static will be initialized with 0 and it will retain it’s value over repeated calls of the function till the program terminates. This is easy to understand from the example below.

void foo()
{
   static int a;   /* Static variable implicitly initialized to zero */
   int b = 0;      /* Automatic variable explicitly initialized to zero */

   a++;
   b++;
   printf("a = %d, b = %d\n", a, b);
}

int main()
{
   int i = 0;
   for(i=0; i<3; i++)
   {
      foo();
   }
}

Output is:

a = 1, b = 1

a = 2, b = 1

a = 3, b = 1

If a global variable is declared as static, it’s scope is limited to that module or file. So it cannot be accessed from another module even by using the “extern” keyword. The compiler is bound to complain if used in such a manner.

The use of the keyword “static” also holds true in case of a function. By default a function is global and can be called from any other module. By declaring a function as static, is can be called only from that particular module.

The benefit of using static global variables and static functions is that they are made private to the module they are declared in. This is very useful in creating libraries as it helps shield the functions which are internal to the library and should not be called by the applications that use it.

foo.c


static int gbl1 = 10;
int gbl2 = 5;

static int foo1()
{
   gbl1++;
   gbl2++
}

int foo2()
{
   gbl1++;
   gbl2++;
   foo1();    /* Static function can be accessed from it's own module */
}

main.c

extern int gbl1;              /* Error: Static variable cannot be accessed as extern */
extern int gbl2;

extern int foo1();           /*Static function cannot be accessed as extern */
extern int foo2();

int main()
{
   foo1();    /*Static function cannot be accessed as extern */
   foo2();
   return 0;
}

 

Related Posts:

Tags: ,

External variables and functions

December 13th, 2009 by Kevin | No Comments | Filed in C Programming

We have seen what is meant by definition and declaration of a variable. In short, declaration of a variable indicates to the compiler the presence of a variable in the source whereas definition indicates that memory has been allocated to a variable.

Variables which have been defined inside a function are automatic and have scope limited to that particular function. A global variable is one which is defined outside the scope of any function. Rather the scope of the global variable is the entire program.

int gbl;   /* Global variable */

int foo()
{
   int a = 100;   /* local(automatic) variable */
   gbl = 10;
   return a;
}

int main()
{
   int b;  /* local(automatic) variable */
   gbl = 20;
   foo();
   printf("gbl = %d", gbl);  /* gbl = 10 */
   return;
}

The concept of external variables comes from the fact that a C program is a collection of files with each file consisting of a module. So if we want to call a function from one module to another, the other module should know about the definition of the function. We use the “extern” keyword and the declaration of the variable to tell the compiler that it exists elsewhere and we want to use it in this particular module.

File 1

int gbl;  /* Global variable */

int foo() /* Global function */
{
   int a = 100;
   gbl = 10;
   return a;
}

File 2

extern int gbl; /* Declaration of an external variable */
extern int foo();   /* Declaration of an external function */

int main()
{
   extern int gbl;  /* Declaration of external variable gbl again with no problem.
                            If "extern" is not used here, it becomes local*/
   int b = 200;
   foo();
   gbl = 20;
   return 0;
}

An external variable should be defined at only one place but it can be declared any number of times. By default, all C functions are external as they are all global and can be called from any module.

Ideally using too many global variables should be avoided in any C program. This is so that we can have minimum interaction between the program modules(something called as coupling). But if we are to use global external variables, it is best to place them in a header file and include the header in whichever modules want to use them.

 

Related Posts:

Tags: , ,