title: snprintf error. argument to sizeof is the same as destination
body: <p>gcc 4.8 give me an error when I build </p>
  
  <pre><code>#include &lt;string.h&gt;
  #include &lt;stdio.h&gt;
  
  static inline void toto(char str[3])
  {
      snprintf(str, sizeof(str), "XX"); 
  }
  
  int main(){
      char str[3]; 
      toto(str);
      return 0;
  }
  </code></pre>
  
  <p>Here is the gcc error</p>
  
  <p><strong>error: argument to ‘sizeof’ in ‘snprintf’ call is the same expression as the destination; did you mean to provide an explicit length?</strong></p>
  
  <p>Note: I m using -Wall -Werror flags which convert warning to error.</p>
  
  <p><a href="https://stackoverflow.com/questions/1775403/using-snprintf-to-avoid-buffer-overruns">There is something similar here</a>
  In a comment, someone answered this</p>
  
  <p><em>"For fixed length buffers, I usually use strncpy(dest, src, sizeof(dest)); dest[sizeof(dest)-1] = '\0'; That guarantees NULL termination and is just less hassle than snprintf not to mention that a lot of people use snprintf(dest, sizeof(dest), src); instead and are very surprised when their programs crash arbitrarily."</em></p>
  
  <p>But this is wrong:
  gcc 4.8 say</p>
  
  <p><strong>"error: argument to ‘sizeof’ in ‘strncpy’ call is the same expression as the destination; did you mean to provide an explicit length? [-Werror=sizeof-pointer-memaccess]"</strong></p>
  
  <p><a href="http://gcc.gnu.org/gcc-4.8/porting_to.html" rel="noreferrer">in gcc 4.8 documentation, they are talking about this issue</a>:
  they say:</p>
  
  <p><em>The behavior of -Wall has changed and now includes the new warning flag -Wsizeof-pointer-memaccess. This may result in new warnings in code that compiled cleanly with previous versions of GCC.</em></p>
  
  <p>For example,</p>
  
  <pre><code>include string.h
  
  struct A { };
  
  int main(void) 
  {
      A obj;
      A* p1 = &amp;obj;
      A p2[10];
  
      memset(p1, 0, sizeof(p1)); // error
      memset(p1, 0, sizeof(*p1)); // ok, dereferenced
      memset(p2, 0, sizeof(p2)); // ok, array
      return 0;
  }
  </code></pre>
  
  <p><em>Gives the following diagnostic:
  warning: argument to ‘sizeof’ in ‘void</em> memset(void*, int, size_t)’ call is the same expression as the destination; did you mean to dereference it? [-Wsizeof-pointer-memaccess]
    memset(p1, 0, sizeof(p1)); // error
                         ^
  Although these warnings will not result in compilation failure, often -Wall is used in conjunction with -Werror and as a result, new warnings are turned into new errors.
  To fix, either re-write to use memcpy or dereference the last argument in the offending memset call.*</p>
  
  <p>Well, in their example, it's obvious the code was wrong, but in my case, with snprintf/strncpy, I dont see why, and I think it's a false positif error of gcc. Right ?</p>
  
  <p>thanks for your help</p>