title: pointer to array not compatible to a pointer to 'const' array?
body: <p>In a C module (aka, compilation unit), I want to have some private data, but expose it <em>read-only</em> to the outside world. I achieve that by having a field in a <code>struct</code> declared in my <code>.c</code> file and a function declared in my <code>.h</code> file that returns a <em>pointer to const</em> to that field. For example, this could look like the following for a <em>string</em>:</p>
  
  <pre><code>// header:
  
  typdef struct foo foo;
  
  const char *foostr(const foo *f);
  
  // implementation:
  
  struct foo
  {
      char *str;
  };
  
  const char *foostr(const foo *f)
  {
      return foo-&gt;str;
  }
  </code></pre>
  
  <p>Now my problem is, I have an array of objects that are themselves arrays. So in my <code>struct</code>, I have a pointer to an array, and from my function, I try to return a pointer to the corresponding <code>const</code> array. Consider the following example code:</p>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;stdint.h&gt;
  
  typedef uint8_t shape[64];
  
  typedef struct foo
  {
      shape *shapes;
  } foo;
  
  
  foo *createfoo(void)
  {
      foo *f = malloc(sizeof *f);
      if (!f) return 0;
  
      // 10 empty shapes:
      f-&gt;shapes = calloc(10, sizeof *(f-&gt;shapes));
  
      if (!f-&gt;shapes)
      {
          free(f);
          return 0;
      }
  
      return f;
  }
  
  const shape *fooshapes(const foo *f)
  {
      return f-&gt;shapes;
  }
  </code></pre>
  
  <p>Compiling this with <code>gcc -c -std=c11 -Wall -Wextra -pedantic</code>, I get the following warning:</p>
  
  <pre class="lang-none prettyprint-override"><code>constarr.c: In function ‘fooshapes’:
  constarr.c:31:13: warning: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic]
       return f-&gt;shapes;
              ~^~~~~~~~
  </code></pre>
  
  <p>I understand a <em>double pointer</em> isn't compatible to a <em>double pointer to const</em>, and also the reason for it, but I don't think this is related, or is it? So, why isn't it allowed to implicitly convert a pointer to an array to a pointer to a <code>const</code> array? And any ideas what I should do instead?</p>
  
  <p>What I did now is adding an explicit cast like this:</p>
  
  <pre><code>const shape *fooshapes(const foo *f)
  {
      return (const shape *) f-&gt;shapes;
  }
  </code></pre>
  
  <p>This of course silences the compiler and I am almost sure it will always work correctly in practice. The "const hole" can't exist in this case, as with an array, there is no non-const inner pointer. But it still leaves me with two further questions:</p>
  
  <ul>
  <li>Is my assumption correct that this doesn't lead to a hole in <code>const</code> correctness?</li>
  <li>Does the explicit cast violate the standard here?</li>
  </ul>