为什么以下代码会给我一个"丢弃限定符"警告?
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]};
这是一件愚蠢的事吗?
答案 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
的调用。