title: Is `memcpy((void *)dest, src, n)` with a `volatile` array safe?
body: <p>I have a buffer that I use for UART, which is declared this way:</p>
  
  <pre><code>union   Eusart_Buff {
      uint8_t     b8[16];
      uint16_t    b9[16];
  };
  
  struct  Eusart_Msg {
      uint8_t             msg_posn;
      uint8_t             msg_len;
      union Eusart_Buff   buff;
  };
  
  struct  Eusart {
      struct Eusart_Msg   tx;
      struct Eusart_Msg   rx;
  };
  
  extern  volatile    struct Eusart   eusart;
  </code></pre>
  
  <p>And here is the function that fills the buffer (which will be sent using interrupts):</p>
  
  <pre><code>void    eusart_msg_transmit (uint8_t n, void *msg)
  {
  
      if (!n)
          return;
  
      /*
       * The end of the previous transmission will reset
       * eusart.tx.msg_len (i.e. ISR is off)
       */
      while (eusart.tx.msg_len)
          ;
  
      if (data_9b) {
          memcpy((void *)eusart.tx.buff.b9, msg,
                  sizeof(eusart.tx.buff.b9[0]) * n);
      } else {
          memcpy((void *)eusart.tx.buff.b8, msg,
                  sizeof(eusart.tx.buff.b8[0]) * n);
      }
      eusart.tx.msg_len   = n;
      eusart.tx.msg_posn  = 0;
  
      reg_PIE1_TXIE_write(true);
  }
  </code></pre>
  
  <p>At the moment of using <code>memcpy()</code>, I know no one else is going to use the buffer (atomic), because the <code>while</code> loop ensures that the last message has been sent, and therefore the interrupt is disabled.</p>
  
  <p>Is it safe to cast away <code>volatile</code> this way so that I am able to use <code>memcpy()</code> or should I make a function maybe called <code>memcpy_v()</code> like these to be safe?:</p>
  
  <pre><code>void *memcpy_vin(void *dest, const volatile void *src, size_t n)
  {
      const volatile char *src_c  = (const volatile char *)src;
      char *dest_c                = (char *)dest;
  
      for (size_t i = 0; i &lt; n; i++)
          dest_c[i]   = src_c[i];
  
      return  dest;
  }
  
  volatile void *memcpy_vout(volatile void *dest, const void *src, size_t n)
  {
      const char *src_c       = (const char *)src;
      volatile char *dest_c   = (volatile char *)dest;
  
      for (size_t i = 0; i &lt; n; i++)
          dest_c[i]   = src_c[i];
  
      return  dest;
  }
  
  volatile void *memcpy_v(volatile void *dest, const volatile void *src, size_t n)
  {
      const volatile char *src_c  = (const volatile char *)src;
      volatile char *dest_c       = (volatile char *)dest;
  
      for (size_t i = 0; i &lt; n; i++)
          dest_c[i]   = src_c[i];
  
      return  dest;
  }
  </code></pre>
  
  <p><strong>Edit:</strong></p>
  
  <p>If I need those new functions,
  given that I know no one is going to modify the array at the same time, would it make sense to use <code>restrict</code> to (maybe) help the compiler optimize (if it can)?
  Possibly this way (correct me if I'm wrong):</p>
  
  <pre><code>volatile void *memcpy_v(restrict volatile void *dest,
                          const restrict volatile void *src,
                          size_t n)
  {
      const restrict volatile char *src_c = src;
      restrict volatile char *dest_c      = dest;
  
      for (size_t i = 0; i &lt; n; i++)
          dest_c[i]   = src_c[i];
  
      return  dest;
  }
  </code></pre>
  
  <p><strong>Edit 2 (add context):</strong></p>
  
  <pre><code>void    eusart_end_transmission (void)
  {
  
      reg_PIE1_TXIE_write(false); /* TXIE is TX interrupt enable */
      eusart.tx.msg_len   = 0;
      eusart.tx.msg_posn  = 0;
  }
  
  void    eusart_tx_send_next_c   (void)
  {
      uint16_t    tmp;
  
      if (data_9b) {
          tmp     = eusart.tx.buff.b9[eusart.tx.msg_posn++];
          reg_TXSTA_TX9D_write(tmp &gt;&gt; 8);
          TXREG   = tmp;
      } else {
          TXREG   = eusart.tx.buff.b8[eusart.tx.msg_posn++];
      }
  }
  
  void __interrupt()  isr(void)
  {
  
      if (reg_PIR1_TXIF_read()) {
          if (eusart.tx.msg_posn &gt;= eusart.tx.msg_len)
              eusart_end_transmission();
          else
              eusart_tx_send_next_c();
      }
  }
  </code></pre>
  
  <p><s>Although</s> <code>volatile</code> <s>may not be</s> <strong>is</strong> needed (I asked it in another question: <a href="https://stackoverflow.com/q/54965075/6872717">volatile for variable that is only read in ISR?</a>)<s>, this question still should be answered in the assumption that <code>volatile</code> is needed so that future users that really need <code>volatile</code> (for example me when I implement the RX buffer), can know what to do.</s></p>
  
  <hr>
  
  <p><strong>EDIT</strong> (Related) (Jul/19):</p>
  
  <p><a href="https://stackoverflow.com/q/56791401/6872717">volatile vs memory barrier for interrupts</a></p>
  
  <p>Basically says that <code>volatile</code> is not needed, and therefore this issue disappears.</p>