Pointers

Pointers are declared using the declarator syntax:

* cv-qualifier-listopt dname

A pointer is a 16- or 32-bit quantity that holds the address of an object. The full declaration, then is:

decl-specifiers * cv-qualifier-listopt dname ;

A simple example of such a declaration is:

char *pch;

The preceding declaration specifies that pch points to an object of type char.

const and volatile Pointers

The const and volatile keywords change how pointers are treated. The const keyword specifies that the value associated with the name that follows can be set only at program startup; the data is protected from modification thereafter.

The volatile keyword specifies that the value associated with the name that follows can be modified by actions other than those in the user application. Therefore, the volatile keyword is useful for declaring objects in shared memory that can be accessed by multiple processes or global data areas used for communication with interrupt service routines.

When a name is declared as volatile, the compiler reloads the value from memory each time it is accessed by the program. This dramatically reduces the possible optimizations. However, when the state of an object can change unexpectedly, it is the only way to ensure predictable program performance.

To declare the object pointed to by the pointer as const or volatile, use a declaration of the form:

const char *cpch;

volatile char *vpch;

To declare the value of the pointer—that is, the actual address stored in the pointer—as const or volatile, use a declaration of the form:

char * const pchc;

char * volatile pchv;

By extension, both the pointer and the object can be declared as const or volatile using the declaration:

const char ch = 'A';

// Object and pointer const.

const char * const cpchc = &ch;

const char * volatile cpchv; // Pointer volatile; object const.

volatile char * const vpchc; // Pointer const; object volatile.

volatile char * volatile cpchc; // Object and pointer volatile.

The C++ language prevents assignments that would allow an object or pointer declared as const to be modified. Such assignments would remove the information that the object or pointer was declared with, thereby violating the intent of the original declaration. Consider the following declarations:

const char cch = 'A';

char ch = 'B';

Given the above declarations of two objects (cch, of type const char, and ch of type char), the following declaration/initializations are valid:

const char *pch1 = &cch;

const char *const pch4 = &cch;

const char *pch5 = &ch;

char *pch6 = &ch;

char *const pch7 = &ch;

const char *const pch8 = &ch;

The following declaration/initializations are erroneous.

char *pch2 = &cch;

char *const pch3 = &cch;

The declaration of pch2 declares a pointer through which a constant object might be modified and is therefore disallowed. The declaration of pch3 specifies that the pointer is constant, not the object; the declaration is disallowed for the same reason the pch2 declaration is disallowed.

The following eight assignments show assigning through pointer and changing of pointer value for the above declarations; for the purposes of this discussion, assume that the initialization had been correct for pch1 through pch8.

*pch1 = 'A'; // Error: object declared const

pch1 = &ch; // OK: pointer not declared const

*pch2 = 'A'; // OK: normal pointer

pch2 = &ch; // OK: normal pointer

*pch3 = 'A'; // OK: object not declared const

pch3 = &ch; // Error: pointer declared const

*pch4 = 'A'; // Error: object declared const

pch4 = &ch; // Error: pointer declared const

Pointers declared as volatile or as a mixture of const and volatile obey the same rules.

Pointers declared as const are often used in function declarations as follows:

char *strcpy( char *szTarget, const char *szSource );

The above statement declares a function, strcpy, that takes two arguments of type “pointer to char” and returns a pointer to type char. Because the arguments are passed by reference and not by value, the function would be free to modify both szTarget and szSource if szSource were not declared as const. The declaration of szSource as const assures the caller that szSource cannot be changed by the called function.

Note:

Because there is a standard conversion from typename * to const typename *, it is legal to pass an argument of type char * to strcpy. However, the reverse is not true; no implicit conversion exists to remove the const attribute from an object or pointer.