Passing volatile array to strncpy

4.3k views Asked by At

In my ISR I have a buffer that gets stuffed from the USART so I declared the buffer as volatile:

volatile uint8_t RxBuffer1[BUFFER_LENGTH];

Ok, no problem there. I believe that is standard practice.

Somewhere in main() I need to copy a portion of that array since the array is a circular buffer and will get obliterated at sometime in the future:

strncpy(Data, RxBuffer1, len);

Oh but this is a no no! my compiler dutifully tells me:

passing argument 2 of 'strncpy' discards 'volatile' qualifier from pointer target type

since strncpy makes 's2' a const char *

I don't think I'm doing anything that hasn't been done as standard practice. How do I do this correctly?

3

There are 3 answers

2
AudioBubble On BEST ANSWER

Cast the argument passed to const char *

2
Tibi On

I think it is better to use memcpy in this case. Strcpy and strncpy are optimized for strings (char arrays).

The syntax is similar to strncpy:

void* memcpy (void* dest, void* src, size_t bytes);

In your case:

memcpy (Data, RxBuffer1, sizeof(uint8_t) * len);

(you can omit sizeof(uint8_t) since it is 1).

0
Mike Moreton On

It's almost certainly safe to cast the volatile away, but technically it's compiler specific.

Volatile just tells the compiler not to apply any optimisations where it puts a copy of some memory in a register, and uses that rather than going back and reading the memory each time.

In the application you're talking about, what you care about is that memcpy shouldn't return the same data as last time you called it, because it hasn't re-read the buffer. But in practice it's extremely unlikely to be implemented that way, as that would mean the compiler storing stuff in registers across function calls. It's theoretically possible, but it doesn't make a lot of sense.

And you almost certainly don't care about memcpy optimising out subsequant copies of the same memory within a single call to memcpy.