Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Discards qualifiers with memcpy

Tags:

c

c99

Why does the following code give me a "discards qualifiers" warning?

double* const a[7];
memcpy(a,b,sizeof(double*)*7);

The error I'm getting with Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn) is

warning: passing 'double *const [7]' to parameter of type 'void *' discards qualifiers

Edit:

Bonus question. Why does the restrict keyword not work either?

double* restrict a[7];
memcpy(a,b,sizeof(double*)*7);

Edit 2:

I'm asking this question, because I want a to be a const restrict pointer. I can get this result with this code:

double* const restrict a[7] = {b[0], b[2], ... b[7]};

Is that a stupid thing to do?

like image 476
hanno Avatar asked Jul 16 '26 07:07

hanno


2 Answers

You're trying to pass a const pointer to a function that expects a non const pointer.

Edit:

More specifically, a is an array whose contents are const pointers to doubles. If you attempted to do a[0] = b[0] (assuming b is defined as double *b[7] or something similar) you would get a compiler error. The results would be the same if you had const char a[7] and attempted a[0] = 'x'.

Calling memcpy as you are allows it to effectively perform the operation above which would otherwise be prohibited.

In the case of restrict, that tells the compiler that the memory pointed to by the given pointer will only be addressed by the given pointer. This allows the compiler to perform certain optimizations.

From Wikipedia:

It says that for the lifetime of the pointer, only it or a value directly derived from it (such as pointer + 1) will be used to access the object to which it points.

Since memcpy is not expecting a restrict * that guarantee is lost, which is why you get the warning. In general, bypassing restrict like this can lead to unpredictable behavior.

like image 191
dbush Avatar answered Jul 18 '26 22:07

dbush


memcpy takes three arguments. The first argument is the place into which the data will be copied. Since the location pointed to by the pointer is going to be modified, whatever the pointer points to must not be constant in order to avoid potential undefined behavior.

Since you pass a, a const pointer, as the first parameter, you get a warning.

Note that the second parameter can point to a const location, because the data is read from it.

The signature of the function looks like this:

void* memcpy(void* dest, const void* src, size_t count);
like image 30
Sergey Kalinichenko Avatar answered Jul 18 '26 22:07

Sergey Kalinichenko



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!