I know that const char *
is a pointer to a const char, while char *const
is a constant pointer to a char.
I am testing this in the following code:<
You can bypass the compiler error by recast it as char*
, as in *((char*)s + 1) = 'a';
but as it was already estated in other answers, this is undefined behaviour and will probably result in Segmentation Fault because you are editing a string literal.
Although string literals in C officially have a type of char[]
(array of char
, not const
), the C standard specifically states that they must be treated as non-modifiable. Compilers tend to put string literals in a read-only segment, so attempting to modify them results in an access violation.
String literals are described in section 6.4.5
of the C11 standard (ISO/IEC 9899:2011).
If you want to test it properly, initialize the strings in a function so the initialization can be dynamic and use strdup()
for that.
int
main(int argc, char **argv)
{
char *d1 = strdup("hello");
char *d2 = strdup("world");
const char *s = d1;
char *const t = d2;
...
free(d1);
free(d2);
}
The d1 and d2 variables are mainly used so that the dynamic allocations can be properly freed using free()
at the end. Also, as other answers suggest, always treat string literals as const char *
.
t
is pointing to a string literal it is undefined behavior to modify a string literal. The C++ draft standard section 2.14.5
String literals paragraph 12 says(emphasis mine):
Whether all string literals are distinct (that is, are stored in nonoverlapping objects) is implementation defined. The effect of attempting to modify a string literal is undefined.
The relevant section from the C99 draft standard is 6.4.5
String literals paragraph 6 which says(emphasis mine):
It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.
On a typical modern Unix platform you will find string literals in the read-only segment which would result in a access violation if we attempt to modify it. We can use objdump to inspect the read-only section as follows:
objdump -s -j .rodata
we can see in the following live example that the string literal will indeed be found in the read-only section. Note that I had to add a printf
otherwise the compiler would optimize out the string literal. Sample `objdump output:
Contents of section .rodata:
400668 01000200 776f726c 64002573 0a00 ....world.%s..
An alternative approach would be to have t
point to an array with a copy of a string literal like so:
char r[] = "world";
char *const t = r ;