Memcpy with destination pointer for const data

I always thought that an expression like const int *a means a is an int pointer to const , and as such should not change the value it points to. Indeed, if you do const int a [] = {1,2,3} and then issue a[0] = 10 , you will get compiler errors.

To my surprise, however, the following compilations are without any warning and work very well.

 #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 it related to cast? When I do memcpy(&a[0], (const void*)&b[0], 3*sizeof(int)); , the compiler immediately 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 *' 
+4
source share
3 answers

Throws usually suppress warnings. There is the gcc option, -Wcast-qual , which will warn you about ghosts that lose the const or volatile qualifier.

The program worked successfully because the memory used to store the array was not actually loaded just because they were allocated on the stack. This is implementation detail and technically your code can be broken if the implementation was really strict.

Declare a and b as global and there is more chance that it will work (still not a guarantee)

+2
source

You told the compiler to ignore the original declaration when you performed the cast. He listened. This does not mean that your program is correct. Changing what was originally declared as const leads to undefined behavior (for example, the compiler can store this data in read-only memory).

C does not hold your hand. If you decide to do something dangerous, this will allow you.

+5
source

Listing void* removes the association using int - by dropping the type, you throw away the type decorators such as const

Edit

As follows from the discussion below, I want to clarify that the important part is not for what you use ( void* in OQ), but the fact that you drop it means discarding the original type and its decorators.

+4
source

Source: https://habr.com/ru/post/1432830/


All Articles