Sunday, May 1, 2011

Constant pointer and pointer to a constant

Declaring pointer to a constant OR constant pointer is always confusing. Following rules will help removing the confusion
1. Constant gets applied to the symbol that appears to its immediate left. If there is no symbol in the left then it gets applied to the symbol which to its immediate right.
2. While reading the variable declaration, always start at the identifier and read backwards.
e.g.
1. const int *I; // No symbol on the left of const so it gets applied to the right symbol i.e. integer.
I is a pointer to a constant integer.
2. int const *I // const gets applied to int (immediate left)
I is a pointer to constant integer.
3. int * const I // const gets applied to pointer (immediate left).
I is a constant pointer to integer.
4. const int* const I ;
I is a constant pointer to constant integer.
5. int const* const I;
I is a constant pointer to constant integer.

Some other useful tips about constants
1. Always use const instead of #define for better type safety. Constants always use implicit linking so its scope is file level. To access const in another file, declare it as extern.
2. Constant can be declared compile time or run time.
e.g. const int i = 10; // compile time constant
const int i = ReadI() // runtime constant.
But once assigned a constant it cannot be changed through out the lifetime of the application.
3. Constants can be declared in class. Instance level constants can be declared as follows
class A
{
const int i; // I is a constant but only for an instance and not at the class level
};
4. Declare class level constant using static const
class A
{
static const int i; // i is constant at class level i.e. across instances of class A.
};
5. Apply const to a function if function cannot change any data members of a class.
6. Dont use const_cast to remove constness of a member variable inside constant funtion since there is no way for a caller to know if function can change class member variable. Instead declare the member variable which can be changed in a constant function as 'mutable'. This gives clear clue to the caller that the constant member function can change mutable member variable.
7. const and volatile takes part in function overloading. So following two are acceptable function declarations.
void foo(int);
void foo(int) const;
void foo(int) volatile;