Monday, 4 March 2013

Qualifiers in C

Today ,I run a program for qualifiers in C.There are basically three qualifiers in C which are used in different styles according to their use :-

1)volatile:-The volatile qualifier maintain consistency of memory access to data objects.The volatile keyword is intended to prevent the compiler from applying any optimization on the code that assume values of variable cannot change "on their own".The volatile keyword is used to declare that an object can be modified in the program by something such as the operating system,the hardware or a concurrently executing thread..It can be used with four types:-

int * volatile ic=&v4;        //a volatile pointer to an integer ,the value of integer can be changed.
volatile int *ci=&v5;        // a pointer to a volatile integer the value of integer cannot be changed .
int volatile *icptr=&v6;       //same as second
volatile int* volatilet cicptr=&v7;       //It is a volatile pointer to a vloatile integer so either  the integer can be changed or the pointer to point anything else.

                                                             The volatile object each time read from memory each time their values is needed and written back to memory each time they changed.The volatile qualifier declares a data object that can its value change in ways outside  the control or detection of the compiler .The compiler is thereby notified not to apply certain optimization to code referring to the project.We can understand it with this example:-

int xyz=100;
while(xyz==100)
{
//code
}

 This program gets compiled ,the compiler may optimize this code.If it finds that the program never ever makes any attempt to change the value of xyz.So it may optimize the code by changing it from "while(xyz==100)"  to "while(true)" because it is slow to compare each time the value of xyz to 100.
                                            But this is not desirable in each case to optimize the code because it is possible in the above case the value of xyz may be changed by an another cause outside the program.which is compiler is not aware of.So In this case we declare the integer xyz as a volatile and it stops the compiler to optimize the code.

volatile int xyz=100;

In C /C++ volatile keyword is intended to:
1)allow access to memory mapped devices
2)allow uses of variables between setjmp and longjmp
3)allow uses of  sig_atomic_t variables in signal handlers

We can use the following program to understand the volatile keyword:-


#include <iostream>
#include <windows.h>
using namespace std;

volatile bool Sentinel = true;
int CriticalData = 0;

unsigned ThreadFunc1( void* pArguments ) {
   while (Sentinel)
      Sleep(0);   // volatile spin lock

   // CriticalData load guaranteed after every load of Sentinel
   cout << "Critical Data = " << CriticalData << endl;
   return 0;
} 

unsigned  ThreadFunc2( void* pArguments ) {
   Sleep(2000);
   CriticalData++;   // guaranteed to occur before write to Sentinel
   Sentinel = false; // exit critical section
   return 0;
}

int main() {
   HANDLE hThread1, hThread2; 
   DWORD retCode;

   hThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadFunc1,
      NULL, 0, NULL);
   hThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadFunc2,
      NULL, 0, NULL);

   if (hThread1 == NULL || hThread2 == NULL)       {
      cout << "CreateThread failed." << endl; 
      return 1;
   }

   retCode = WaitForSingleObject(hThread1,3000);

   CloseHandle(hThread1);
   CloseHandle(hThread2);

   if (retCode == WAIT_OBJECT_0 && CriticalData == 1 )
      cout << "Success" << endl;
   else
      cout << "Failure" << endl;
}

In this we can see that there is two thread handler declare which called two thread functions which are executed parrallely.In the first function we can see that the Sentinel is true so the function is in an infinite loop .When the second function starts its execution parrallaly the value of critical data incremented to one and the the value of Sentinel become false  and the value of critical data is printed one. 


2)Const:-The const qulaifier explicitly declares an data object that cannot be changed .Its value is set at initialization.We cannot use a const variable in expression requiring a modifiable lvalue.It can be used with four types:-
int * const ic=&v4;        //a const pointer to an integer ,the value of integer can be changed.The value of pointer cannot be changed
const int *ci=&v5;        // a pointer to a const integer the value of integer cannot be changed .The value of pointer can  be changed   .

int const *icptr=&v6;       //same as second
const int* const cicptr=&v7;       //It is a const pointer to a const integer so neither  the integer can be changed nor the point to anything else.
These 4 variation we can easily understand with these figures:-




We can easily understand it with the help of program snapshot:-

 





























*Commented lines are shows that these  const variables are not modifiable which we explained above.

3)restrict:-Basically there are two keywords _restrict and restrict_declspec.The _restrict keyword is valid only on variables .When restrict is used ,the compiler will not propagate the no-alias property of a variable.That is ,if you assigned a _restrict variable to a non-restrict variable ,the compiler will not imply that the non-_restrict variable is not aliased.The _restrict keyword similar to the restrict_declspec but _restrict can be used in C or C++ program.The restrict_declspec  is not a keyword in standard C/C++.It is a keyword C99 compiler .So if we use C99 compiler then it works fine.The restrict qualifier is only applied to a pointer .We know that a pointer is the address of a location in the memory.More than one pointer can access the same chunk of memory and modify it during the course of a program.But If we use restrict type of qualifier,it indicates to compiler if the memory addressed by the restrict-qualified pointer is modified ,then no other pointer will access the same memory .We can declare a restrict pointer by following syntax:-


 int * __restrict  f;

Here is snapshot for behaviour of a restricted variable.




No comments:

Post a Comment