I always thought that an statement like const int *a means a is an int pointer to const data and as such one should not be able to modify the value it points to. Indeed if you do const int a [] = {1,2,3} and then issue a[0] = 10 you’ll get compiler errors.
To my surprise, however, the following compiles without any warning and runs just fine.
#include <stdio.h>
#include <string.h>
int main (){
const int a [] = {1, 1, 1};
const int b [] = {2, 2, 2};
memcpy((void*) &a[0], (const void*)&b[0], 3*sizeof(int));
int i;
for (i=0; i<3; i++) printf("%d\n",a[i]);
return 0;
}
Why is this allowed? Is this due to the cast? When I do memcpy(&a[0], (const void*)&b[0], 3*sizeof(int)); compiler promptly generates the following warning:
cpy.c: In function ‘main’:
cpy.c:9:3: warning: passing argument 1 of ‘memcpy’ discards ‘const’ qualifier from pointer target type [enabled by default]
/usr/include/string.h:44:14: note: expected ‘void * __restrict__’ but argument is of type ‘const int *’
Casts usually suppress warnings. There is a gcc option,
-Wcast-qualthat will warn you about casts that are losing aconstorvolatilequalifier.The program ran successfully because the memory used to store the array wasn’t actually readonly, because they were allocated on the stack. This is an implementation detail and technically your code could have crashed if the implementation was really strict.
Declare
aandbas globals and there’s a greater chance it will crash (still not a guarantee)