1

I'm getting warning like this on xc32 compiler (gcc based microcontroller compiler, not open-source).

modem_uart.c:66:5: warning: passing argument 1 of 'memset' discards 'volatile' qualifier from pointer target type [enabled by default]

Here is the code:

#include <string.h>
// (...)
volatile char rxbuf[MODEM_UART_RXBUF_SIZE];
// (...)

void some_function(void)
{    
    // (...)
    memset(rxbuf, 0, MODEM_UART_RXBUF_SIZE); // <- warning here
    // (...)
}

Can someone explain why compiler is discarding volatile?

Kamil
  • 13,363
  • 24
  • 88
  • 183

2 Answers2

2

The specification in the standard of memset has the following declaration:

void *memset(void *s, int c, size_t n);

The first argument is not declared volatile void *s. So it doesn't guarantee to obey the extra restrictions on accessing volatile data. Making every call to memset() treat the destination as if were volatile would impose an unnecessary performance impact.

If you need those assurances, you should replace the memset() call with an explicit loop.

for (int i = 0; i < MODEM_UART_RXBUF_SIZE; i++) {
    rxbuf[i] = 0;
}

If you need this from multiple places in your code, you could put it into a volatile_memset() function.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Can I add `register` modifier for `i` inside `for` to make it faster? Well, that could be a subject for another question... – Kamil Oct 05 '20 at 19:52
  • That's practically never needed. Compilers are good at figuring out which variables would get the most benefit from being in registers. – Barmar Oct 05 '20 at 19:53
  • @Kamil How could forcing the compiler to do something that it already can do if it's the fastest option possibly make your code any faster? – David Schwartz Oct 05 '20 at 20:18
  • @Kamil In general, the `register` modifier is considered obsolete. It was useful years ago when optimizers weren't as clever as they are now. – Barmar Oct 05 '20 at 20:45
  • @Barmar Well, this is microcontroller compiler, I don't know on which gcc version is it based on, there is probably custom optimizer code (not written by crowd, probably few guys in Microchip)... Maybe I will check that it in the disassembler window. – Kamil Oct 06 '20 at 17:40
1

Your platform doesn't provide a memset function that is guaranteed to respect whatever guarantees it provides for volatile. So, in order to call memset, the compiler must discard the volatile qualifier on rxbuf.

You should probably write your own implementation of memset that respects whatever guarantees you expect volatile to provide for you. This answer includes one for memcpy to solve a similar problem. If there are no such guarantees, then get rid of volatile.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278