我有一个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
);
Run Code Online (Sandbox Code Playgroud)
我收到这个警告:
从指针目标类型传递'
memcpy'discards'volatile'限定符的参数2
是一种更安全的方式阅读部分或更好的方式来使用memcpy并防止这种警告?
R..*_*R.. 13
memcpy与volatile对象不兼容,函数签名中不匹配的指针类型有助于指出这一点.memcpy可以以任何顺序复制,以任何单位大小,多次读取源的部分,多次写入目的地的部分,等等.另一方面,volatile表达了对对象的序列和访问次数必须准确的意图他们将在抽象机器中做什么.如果要复制volatile数组,则需要编写自己看起来像天真的复制循环memcpy,并volatile在循环中使用正确的类型作为指针.
一般的建议是不使用memcpy的硬件外设寄存器或volatile一般合格的对象,甚至当且仅当它们占据间隙更少的内存区域.他们通常需要特定的访问模式memcpy并不能保证.这包括使用优化的更宽传输,多次访问相同位置或更改访问顺序.
由于上述原因和以下原因,甚至不要考虑丢掉volatile限定符!编译器可以很好地优化呼叫(例如,如果您有两个相同的呼叫而不更改源和目标区域之间),组合两个访问或在其他硬件访问之前/之后移动呼叫.
而是编写自己的复制函数/循环来保持限定符.这将迫使编译器生成完全符合您需要的代码.请记住为复制指针使用正确的类型.另请注意,标准整数类型不是特定大小的硬件寄存器的理想选择.从使用固定宽度类型stdint.h一样uint8_t,uint16_t...来代替.