使用memcpy丢弃限定符

时间:2015-07-14 13:59:14

标签: c c99

为什么以下代码会给我一个"丢弃限定符"警告?

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

Apple LLVM版本6.1.0(clang-602.0.53)(基于LLVM 3.6.0svn)的错误是

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

修改

奖金问题。为什么restrict关键字也不起作用?

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

编辑2:

我问这个问题,因为我希望a成为const restrict指针。我可以使用以下代码获得此结果:

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

这是一件愚蠢的事吗?

4 个答案:

答案 0 :(得分:5)

您正在尝试将const指针传递给需要非常量指针的函数。

编辑:

更具体地说,a是一个数组,其内容为const指向双精度的指针。如果您尝试a[0] = b[0](假设b被定义为double *b[7]或类似的东西),您将收到编译器错误。如果您有const char a[7]并尝试a[0] = 'x',则结果会相同。

按原样调用memcpy可以有效地执行上面禁止操作的操作。

restrict的情况下,它告诉编译器给定指针指向的内存只能由给定的指针寻址。这允许编译器执行某些优化。

来自Wikipedia

  

它表示指针的生命周期,只有它或一个值   直接从它派生(如指针+ 1)将用于访问   它指向的对象。

由于memcpy并不期望保证失去restrict *,因此您会收到警告。通常,绕过这样的restrict会导致不可预测的行为。

答案 1 :(得分:2)

因为a是常量。

double* const a[7];是一个由7个指针组成的数组。这个数组(!,而不是指向的双精度数)标记为const。 memcpy的第一个参数是目标,它不是const(因此可以写入)。因此,不允许将const a作为非const目标传递给memcpy。

答案 2 :(得分:2)

memcpy有三个参数。第一个参数是数据将被复制到的位置。由于指针指向的位置将被修改,无论指针指向哪个都必须是常量,以避免潜在的未定义行为。

由于您传递a const指针作为第一个参数,因此会收到警告。

请注意,第二个参数可以指向const位置,因为从中读取数据。

该功能的签名如下所示:

void* memcpy(void* dest, const void* src, size_t count);

答案 3 :(得分:1)

在此次电话会议中

memcpy(a,b,sizeof(double*)*7);

可以用以下方式写得更简单

memcpy( a, b, sizeof( a ) );

function memcpy更改了数组a的元素,因为它将数组b的元素复制到数组a的元素中。

然而,数组a的声明看起来如下

const T a[7];

其中T可以定义为

typedef double * T;

那就是你试图改变一个常量数组,编译器会警告你这个有未定义行为的操作。

我怀疑你可能是指另一个数组a的声明,例如

const double * a[7];

在这种情况下,您可以使用函数memcpy的调用。