Wednesday, June 20, 2012

Volatile Keyword

"volatile" keyword is used when we don't want compiler to optimize our code. Compiler optimization is something when we refer a variable multiple times, compiler optimizes this instruction by single load instruction and then referr to the register for every access (Compiler converts high level language to assembly language).
So if we declare variable with "volatile" keyword, compiler will not optimize its instruction for this particular variable.
For Example - consider below C program:



Now the assembly conversion (run command - "gcc -S filename.c" in terminal - linux)



Now we will see the volatile keyword's real impact - we have just changed our variable's declaration as volatile as shown below:



Now see the assembly conversion below:


In the above program, we could clearly see that every time there is load instruction followed by save instruction in case of volatile. Now fundamentally we are clear about "volatile" keyword.

But we haven't thought about the need of such type of variables. Volatile keyword is useful when we have many threads sharing the same variables so that whenever a thread try to retrieve the value, there will always be a load instruction (to get correct value) and in the same way there will be save instruction as well.
Or when we have shared hardware between drivers or third party, there also volatile variables are used.
---------------------------------------------------------------------------

Now if we declare volatile pointer variable, will it make any sense? think?
We know pointers holds the address of another memory location, so when we try to retrieve the value, it will always get retrieved from the address i.e. you will always retrieve the value from memory addresses. So if you are retrieving value through a pointer variable then it doesn't make any difference whether pointer is volatile or not. So shall never declare pointers as volatile (it doesn't make any difference).



Monday, June 18, 2012

Const keyword

"const" keyword stands for constants (once declared, not modifiable). In programming language, we use variables to have identification for our real values. So variables are nothing but represents a memory location where our data gets stored. Whenever we want to access data, we can directly retrieve it by referring our variable. In the same way, we can change the data.
For Example:
int data = 100; // data is the variable name, 100 is the value.
data  = data + 10; //modifying the variable's value.
int t = data; //getting value to another variable through old variable.

Now consider a case (mathematical) where we need pi's value (3.14) to get our result. We are sure that pi's value will never change then if we use this value to our normal variable then compiler allow us to modify it. Example:
int pi = 3.14;
pi = pi + 10; //not expected as we know that pi's value cannot be 13.14.

So we need a way to tell the compiler that don't consider this identifier modifiable. We can do that with "const" keyword. Compiler knows the meaning of const and then he will not allow you to modify the value at compile time itself.
Example:
const int pi = 3.14;
pi = pi + 10;//Error: assignment of read-only variable 'pi'

It is really good practice to use const in our program when we know that its value will always be constant.
Till now we discussed "const" in terms of variable's value, but what about pointers (of-course pointer is also a variable holding memory location as its value". Now see below line:

const char *char_ptr = "data is constant""; //What you think? What is char_ptr?
*char_ptr = 'D';//Will compiler allow us to modify the string.
char_ptr = "pointer is not constant";//Will compiler allow us to modify the pointer.

Here 'char_ptr' is a pointer variable pointing to a constant data (i.e. "about const"). If we try to modify the data where this pointer points to, we will get compile time error (i.e. *char_ptr = 'D' will give Error: assignment of read-only variable '* char_ptr'). But pointer is not constant here, so it can point to another data (i.e. char_ptr = "pointer is not constant").
What if we declare pointer like below:

char * const char_ptr = "pointer is constant";
*char_ptr = 'P';
char_ptr = "data is not constant"; //Error: assignment of read-only variable 'char_ptr'

This time our pointer variable (char_ptr) is constant, it can't be assigned. So the compiler will give error at line - char_ptr = "data is not constant". But will allow us to modify the contents of the data i.e.- *char_ptr = 'P'.
Now we have clarity about "const" keyword.
---------------------------------------------------------------------
const int data = 100;//variable data is constant.
const char *char_ptr  = "data is constant";//data where the pointer is pointing to is constant.
char * const char_ptr = "point is constant";//pointer variable char_ptr is constant.
const char * const char_ptr  = "data and pointer are constants";//pointer variable char_ptr and the data where this pointer is pointing to are constants.
---------------------------------------------------------------------

const int data = 3.14;//variable data is constant
int const data = 3.14;//variable data is constant
above both the lines are same (i.e. const int == int const), in both the cases data is the constant variable.
---------------------------------------------------------------------

Please note that constant variables can't be assigned, they are always initialized.

Sunday, June 17, 2012

new - delete Operators in C++

In our general communication language, if we observe something first time then we say it NEW.

Now consider a computer language, what is the basic thing needed by a program i.e. Memory. For running a program, we need memory for code instructions, we need memory for variables.
Now we have compile time memory and run-time memory allocations.

Code instructions will always be mapped to address locations at compile time only.
But when it comes to data variables, we can have compile time variables and run time variables.
Compiler will always maps the compile time variables with the addresses (Globals, Static etc.).
Run-time memory allocations happens in two ways:
1. Stack variables - happens implicitly and will be valid till the scope (local stack variables).
2. Heap variables - Programmer has to explicitly request for allocation and in the same way he has to explicitly request for deallocation from the heap (dynamic allocation).

Now come to the "new" keyword. In C++, Java etc, "new" keyword is used to allocate memory at run-time dynamically. The memory will be allocated in the heap section (similar to malloc / calloc in C).
Here our focus is on "new" operator in C++. So we will be discussing by considering c++ as our reference language.
new operator not only allocate memory at run time but does more then just allocation (compare to malloc / calloc). It invokes constructors, it returns the allocated address in appropriate Data Type format (we don't need to explicitly type cast the return address), we can overload new operator to provide placement new (managing preallocated buffer - placement new kind of functionality). We say new as a operator because C++ allows us to overload the operators and then we can overload new operator to have our own defined memory management.

Below is the examples of new operator:
-----------------------------------------------
Example [1]: normal new operator
class A{
...
...};


int main()
{
   A *a1 = new A(); //invokes the default constructor of class A and type casts the address to class A * type
   A *a2 = new A(10, 20); //invokes parameterised constructor of class A
   return 0;
}

Example [2]: placement new operator

char *buffer = new char[1000];
String *s1 = new(buf) String("First");
String *s2 = new(buf) String("Second");
------------------------------------------------


Now come to little bit in detail, when we say "new A()", the compile first invokes "operator new" (if defined - overloaded") and allocates the chunk of bytes then it invokes the constructor of class A and initializes the memory.

We can even allocate memory without calling the constructor as:

A *a1 = operator new(sizeof(A)); //this is similar to malloc call in C

----------------------------------------------------------------------------------------------------------

Now we know new allocates memory from the heap and will be reserved for the whole life of the program until we don't make call to deallocate the space (same as we make call to allocate). To deallocate the memory, we use delete operator. delete operator invokes the destructor of the class and then deallocates the object from the memory. In case of placement new, we need to overload delete (same - as we do for new operator) and then manage appropriately

---------------------------------------------------------------------------------------------------------

Please note that I assumed that the reader is having basic knowledge of C++ programming and programming concepts.