Passing argument 2 of 'memcpy' discards the 'volatile' qualifier from the target pointer type

I have volatile char * start_address; , which points to register sections (may change due to hardware behavior). I need to read it and I use:

 memcpy ( result_p, // starting address of destination start_address, // starting address of source result_len // for the length of the payload ); 

I get this warning:

passing argument 2 of ' memcpy ' discards ' volatile ' from target type

Is a safe way to read partitions or a better way to use memcpy and prevent this warning?

+5
source share
3 answers

memcpy incompatible with mutable objects, and a mismatched pointer type in the function signature helps to indicate this. memcpy can copy in any order, in any unit size, read parts of a source several times, write parts of a destination several times, etc. On the other hand, volatile expresses the intention that the sequence and number of calls to the object should be exactly what they will be in the abstract machine. If you want to copy volatile arrays, you need to write your own copy loop, which looks like naive memcpy , and use the correct volatile type for the pointer in your loop.

+12
source

The general advice is not to use memcpy for hardware peripheral registers or volatile qualified objects in general, even iff , they occupy an area without memory. Usually they need a specific access pattern memcpy does not guarantee. This includes using optimized wider gears, accessing the same location at the same time, or changing access order.

For reasons above and below, don't even think about dropping the volatile qualifier! The compiler can optimize the call very well (for example, if you have two identical calls without changes in the source and intermediate channels), combine the two accesses or move the call before / after another access to the hardware.

Instead, write your own copy function / loop, keeping the qualifier. This will cause the compiler to generate code that does exactly what you want. Remember to use the correct type for pointers to copies. Also note that standard integer types are not a good choice for hardware registers of a certain size. Use fixed-width types from stdint.h like uint8_t , uint16_t , ... instead.

+4
source

Choose language! In C ++ you can use std::copy . It will accept any type of (input) iterator, and a pointer to volatile is a valid input iterator.

+1
source

Source: https://habr.com/ru/post/1247472/


All Articles