我有volatile char * start_address;
指向寄存器部分(可能因硬件行为而改变)。我需要阅读它并且我正在使用:
memcpy (
result_p, // starting address of destination
start_address, // starting address of source
result_len // for the length of the payload
);
我收到了这个警告:
传递“
memcpy
”的参数2,丢弃“volatile
”限定符 指针目标类型
阅读这些部分是一种更安全的方式,还是更好的方法来使用memcpy并阻止此警告?
答案 0 :(得分:13)
memcpy
与易失性对象不兼容,函数签名中不匹配的指针类型有助于指出这一点。 memcpy
可以按任何顺序复制,以任何单位大小,多次读取源的部分,多次写入目标的部分,等等。另一方面,volatile
表示序列的意图对象的访问次数必须与抽象机中的访问次数完全相同。如果要复制volatile
数组,则需要编写自己的复制循环,看起来像一个天真的memcpy
,并使用正确的volatile
类型作为循环中的指针。
答案 1 :(得分:7)
一般建议不要将memcpy
用于硬件外设寄存器或volatile
限定对象,即使 iff 它们也会占用无间隙内存区域。他们通常需要特定的访问模式memcpy
并不能保证。这包括使用优化的更宽传输,多次访问相同位置或更改访问顺序。
由于上述原因和以下原因,请不要考虑丢弃volatile
限定词!编译器可以很好地优化呼叫(例如,如果您有两个相同的呼叫而不更改源和目标区域之间),则组合两次访问或在其他硬件访问之前/之后移动呼叫。
而是编写自己的复制函数/循环来保持限定符。这将迫使编译器生成完全符合您需要的代码。请记住为复制指针使用正确的类型。另请注意,标准整数类型不是特定大小的硬件寄存器的理想选择。使用stdint.h
中的固定宽度类型,例如uint8_t
,uint16_t
,...,
答案 2 :(得分:1)
在C ++中,您可以使用std::copy
。它将采用任何类型的(输入)迭代器,而 volatile
的指针是一个完全有效的输入迭代器。