Thursday, December 17, 2009

const keyword in C and C++

Given the following:
char my_string[] = "12345";
You can create a pointer to this char array with, or without, the "const" keyword. The four options are these:
char *my_ptr1 = my_string;
char *my_ptr2 const = my_string;
const char *my_ptr3 = my_string;
const char *my_ptr4 const = my_string;
These all point to the '1' in "12345".


For "my_ptr1", any of the following operations are legal:
my_ptr1 = my_string + 1; // now points to '2' in "12345"
*my_ptr1 = '8'; // '1' in "12345" is changed to an '8', making "82345"
(*my_ptr1)++; // '1' in "12345" is changed to an '2', and my_ptr1 now points to the second '2' in "22345"

For "my_ptr2", the following are legal:
my_ptr2 = my_string + 1; // now points to '2' in "12345"
my_ptr2++; // also points to '2' in "12345"
However, you cannot change the value of "my_string" in any way. This means that
*my_ptr1 = '8';
would not change the string to "82345", but instead your compiler would inform you that this is an illegal operation.


For "my_ptr3", the following is legal:
*my_ptr3 = '8'; // '1' in "12345" is changed to '8', making "82345"
However, changing the address where it pointed to would be illegal:
my_ptr3 = my_string + 1;
my_ptr3++;
Having the "const" identifier AFTER the pointer declaration means that the pointer can't move or be changed, although the data CAN be.


Finally, there's "my_ptr4". You cannot change the address of my_ptr4 (same restrictions as my_ptr3 has), nor can you change the data that it is pointing at (same restrictions as my_ptr2).

None of these are legal operations:
my_ptr4 = my_string + 1;
my_ptr4[1] = '8';
If you want to see some of this in action, check out the following code. Change line 6
char *my_ptr = my_string;
to include the "const" keyword in various places as shown above to see the different kinds of compiler warnings/errors you get. (Tested with i686-apple-darwin8-gcc-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc. build 5367) compiler.)

#include

int main()
{
char my_string[] = "12345";
char *my_ptr = my_string; // you could also use "&my_string[0]", which is the same thing


// Before any modifications
printf("my_string: \"%s\"\n", my_string);
printf("my_ptr is pointing to the \'%c\' in \"%s\"\n", *my_ptr, my_string);


// This will change my_string to equal "18345"
my_ptr[1] = '8';

printf("\n");
printf("my_string now equals: \"%s\"\n", my_string);


// This will make my_ptr point to the '8' in "18345"
my_ptr++;

printf("\n");
printf("my_ptr is now pointing to the \'%c\' in \"%s\"\n", *my_ptr, my_string);


// This will change the '8' in "18345"
(*my_ptr)++;

printf("\n");
printf("my_string now equals: \"%s\"\n", my_string);
printf("my_ptr is now pointing to the \'%c\' in \"%s\"\n", *my_ptr, my_string);


return 0;
}