3

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?

BЈовић
  • 62,405
  • 41
  • 173
  • 273
user1160866
  • 157
  • 2
  • 10
  • You can cast it to const char *. –  Jan 20 '12 at 15:20
  • 1
    Ding ding ding. we have a winner! Thank you. That did indeed get rid of the error however I feel nervous about it. Am I really just masking the problem or is that really how the "pros" do it? – user1160866 Jan 20 '12 at 15:45

3 Answers3

2

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).

Tibi
  • 4,015
  • 8
  • 40
  • 64
  • No joy. memcpy does the same thing as strncpy with regard to this error. Casting as (const char *) did it. – user1160866 Jan 20 '12 at 15:45
  • I just wanted to note that yes, you are right memcpy would be better in this situation but it just didn't solve the casting problem. Thanks for the help. – user1160866 Jan 20 '12 at 17:44
2

Cast the argument passed to const char *

  • Well, I have to revive this thread. I made some changes for other reasons and now this line isn't working again. Here is the details: – user1160866 Feb 05 '12 at 05:27
  • casting away volatile only silences the compiler, it doesn't solve the underlying problem that the error highlights. volatile means that the values in the array may be modified external to the program, and tells the compiler to emit code re-reading that memory at every access. – Arvid Mar 21 '17 at 22:03
-1

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.

Mike Moreton
  • 128
  • 1
  • 8