Pointer and arrays are different. Defining string constants as pointers or arrays fits different purposes.
When you define a global string constant that is not subject to change, I would recommend you make it a const array:
const char product_name[] = "The program version 3";
Defining it as const char *product_name = "The program version 3";
actually defines 2 objects: the string constant itself, which will reside in a constant segment, and the pointer which can be changed to point to another string or set to NULL
.
Conversely, defining a string constant as a local variable would be better done as a local pointer variable of type const char *
, initialized with the address of a string constant:
int main() {
const char *s1 = "world";
printf("Hello %s\n", s1);
return 0;
}
If you define this one as an array, depending on the compiler and usage inside the function, the code will make space for the array on the stack and initialize it by copying the string constant into it, a more costly operation for long strings.
Note also that const char const *s3 = "baz";
is a redundant form of const char *s3 = "baz";
. It is different from const char * const s3 = "baz";
which defines a constant pointer to a constant array of characters.
Finally, string constants are immutable and as such should have type const char []
. The C Standard purposely allows programmers to store their addresses into non const pointers as in char *s2 = "hello";
to avoid producing warnings for legacy code. In new code, it is highly advisable to always use const char *
pointers to manipulate string constants. This may force you to declare function arguments as const char *
when the function does not change the string contents. This process is known as constification and avoid subtile bugs.
Note that some functions violate this const
propagation: strchr()
does not modify the string received, declared as const char *
, but returns a char *
. It is therefore possible to store a pointer to a string constant into a plain char *
pointer this way:
char *p = strchr("Hello World\n", 'H');
This problem is solved in C++ via overloading. C programmers must deal with this as a shortcoming. An even more annoying situation is that of strtol()
where the address of a char *
is passed and a cast is required to preserve proper constness.