Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 406 Vote(s) - 3.52 Average
  • 1
  • 2
  • 3
  • 4
  • 5
memcpy with destination pointer to const data

#1
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 *’
Reply

#2
You told the compiler to disregard the initial declaration when you performed the cast. It listened. That doesn't mean that your program is correct however. Modifying what was originally declared to be `const` results in undefined behavior (for example, the compiler is free to store that data in read only memory).

C doesn't hold your hand. If you chose to do something dangerous then it will let you.
Reply

#3
Casts usually suppress warnings. There is a gcc option, `-Wcast-qual` that will warn you about casts that are losing a `const` or `volatile` qualifier.

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 `a` and `b` as globals and there's a greater chance it will crash (still not a guarantee)
Reply

#4
Casting to `void*` removes the association with an `int` - by throwing away the type, you throw away the type decorators, such as `const`

**Edit**

As from discussion below, I want to make clear, that the important part is not **to what** you cast (`void*` in the OQ), but the fact **that** you cast - this implies throwing away your original type and its decorators.
Reply



Forum Jump:


Users browsing this thread:
2 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through