title: Using volatile twice in an R-value
body: <p>The statement:</p>
  
  <pre><code>volatile unsigned char * volatile p = (volatile unsigned char * volatile)v;
  </code></pre>
  
  <p>Generates a warning C4197 in MSVC v14.1:</p>
  
  <blockquote>
    <p>Warning C4197: 'volatile unsigned char *volatile ': top-level volatile in cast is ignored</p>
  </blockquote>
  
  <p>The 2011 C standard (section [N1570] 6.7.3 4.) states:  “The properties associated with qualified types are meaningful only for expressions, that are l-values”, thus the top-level volatile in this cast is ignored and generates this warning.</p>
  
  <p>The author of this code states, that it doesn't violate the C standard and is required to prevent some GCC optimizations.
  He illustrates the problem with the code at: <a href="https://godbolt.org/g/xP4eGz" rel="nofollow noreferrer">https://godbolt.org/g/xP4eGz</a></p>
  
  <pre><code>#include &lt;stddef.h&gt;
  
  static void memset_s(void * v, size_t n) {
    volatile unsigned char * p = (volatile unsigned char *)v;
    for(size_t i = 0; i &lt; n; ++i) {
      p[i] = 0;
    }
  }
  
  void f1() {
    unsigned char x[4];
    memset_s(x, sizeof x);
  }
  
  static void memset_s_volatile_pnt(void * v, size_t n) {
    volatile unsigned char * volatile p = (volatile unsigned char * volatile)v;
    for(size_t i = 0; i &lt; n; ++i) {
      p[i] = 0;
    }
  }
  
  void f1_volatile_pnt() {
    unsigned char x[4];
    memset_s_volatile_pnt(x, sizeof x);
  }
  </code></pre>
  
  <p>...where he shows that the function f1() compiles to nothing (just a ret instruction) but f1_volatile_pnt() compiles to instructions that do the intended job.</p>
  
  <p><strong>QUESTION</strong>:  Is there a way to properly write this code so that it is compiled correctly by GCC and in accordance with the 2011 C standard (section [N1570] 6.7.3 4.) so it does not generate the warning with MSVC and ICC ?   ...without #ifdef...</p>
  
  <p>For the context of this problem, see: <a href="https://github.com/jedisct1/libsodium/issues/687" rel="nofollow noreferrer">https://github.com/jedisct1/libsodium/issues/687</a></p>