title: Can we safely call C API functions from C++ when arrays are involved?
body: <p>Context:</p>
  
  <p>As an old C programmer (even K&amp;R C...) I had always believed that an array was nothing more than <em>contiguously allocated nonempty set of objects with a
  particular member object type, called the element type</em> (from n1570 draft for C11 standard, 6.2.5 Types). For that reason I did not worry too much about pointer arithmetics.</p>
  
  <p>I now know that an array is an object type and that it can be only created <em>by a definition (6.1), by a new-expression (8.3.4), when implicitly changing the active member of a
  union (12.3), or when a temporary object is created (7.4, 15.2)</em> (from n4659 draft for C++17).</p>
  
  <p>Problem:</p>
  
  <p>I have to use a C library in which some functions return pointers to arrays of C structs. So far so good, a C struct is a POD type, and proper padding and alignment is achieved by using the standard flags of the compiler. But as the size of the array is only known at runtime, even with the correct <code>extern "C"</code> declarations, my function is declared to return a pointer to the first element of the array - the actual size is returned by a different function of the API.</p>
  
  <p>Simplified example:</p>
  
  <pre><code>#include &lt;iostream&gt;
  
  extern "C" {
      struct Elt {
          int ival;
          //...
      };
  
      void *libinit();                 // initialize the library and get a handle
      size_t getNElts(void *id);       // get the number of elements
      struct Elt* getElts(void *id);   // get an access the the array of elements
      void libend(void *id);           // releases library internal data
  }
  
  int main() {
      void *libid = libinit();
      Elt* elts = getElts(libid);
      size_t nelts = getNElts(libid);
      for(int i=0; i&lt;nelts; i++) {
          std::cout &lt;&lt; elts[i].ival &lt;&lt; " ";    // is elts[i] legal?
      }
      std::cout &lt;&lt; std::endl;
      libend(libid);
      return 0;
  }
  </code></pre>
  
  <p>Question:</p>
  
  <p>I know that the bloc of memory has probably been allocated through <code>malloc</code>, which could allow to use pointers on it and I assume that <code>getElts(libid)[0]</code> does not involve Undefined Behaviour. But is it legal to use pointer arithmetics over the C array, when it has never been declared as a C++ array: the API only guarantees that I have a <em>contiguously allocated set of objects of type Elt</em> and that <code>getElts</code> returns a pointer to the first element of that set.</p>
  
  <p>Because [expr.add] explicitely restrict pointer arithmetics inside an array:</p>
  
  <blockquote>
    <p>4 When an expression that has integral type is added to or subtracted from a pointer, the result has the type
    of the pointer operand. <strong>If the expression P points to element x[i] of an array object x</strong> with n elements,
    the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element
    x[i + j] <strong>if 0 &lt;= i + j &lt;=n</strong>; <strong>otherwise, the behavior is undefined</strong>... </p>
  </blockquote>
  
  <p>That used to be a common pratice...</p>
  
  <h3>EDIT</h3>
  
  <p>In order to make more clear my question, I know that <em>this</em> would be UB if done in C++</p>
  
  <p>libstub.c++</p>
  
  <pre><code>/* C++ simulation of a C implementation */
  extern "C" {
      struct Elt {
          int ival;
          //...
      };
  
      void *libinit();                 // initialize the library and get a handle
      size_t getNElts(void *id);       // get the number of elements
      struct Elt* getElts(void *id);   // get an access the the array of elements
      void libend(void *id);           // releases library internal data
  }
  
  size_t getCurrentSize() {
      return 1024;    // let us assume that the returned value is not a constexpr
  }
  
  void *libinit() {
      size_t N = getCurrentSize();
      unsigned char * storage = new unsigned char[(N + 1) * sizeof(Elt)];
      // storage can provide storage for a size_t correct alignment
      size_t *n = new(storage) size_t;  
      *n = N;
      for (size_t i=1; i&lt;=N; i++) {
          // storage can provide storage for a size_t, correct alignment
          Elt *elt = new(storage + (i+1) * sizeof(Elt)) Elt();
          elt-&gt;ival = i;           // put values into elt...
      }
      return static_cast&lt;void *&gt;(storage);
  }
  
  void libend(void * id) {
      unsigned char *storage = static_cast&lt;unsigned char *&gt;(id);  // ok, back cast is valid
      delete[] storage;   // ok, was allocated by new[]
  }
  
  size_t getNElts(void *id) {
      size_t *n = reinterpret_cast&lt;size_t *&gt;(id);    // ok a size_t was created there
      return *n;
  }
  
  Elt *getElts(void *id) {
      unsigned char *storage = static_cast&lt;unsigned char *&gt;(id); // ok, back cast
      Elt* elt = reinterpret_cast&lt;Elt *&gt;(storage + sizeof(Elt)); // ok an Elt was created there
      return elt;
  }
  </code></pre>
  
  <p>This is valid C++ code, and it fullfills the C API requirement. The problem is that <code>getElts</code> returns a pointer to a single element object which is not member of any array. So according to [expr.add] pointer arithmetics based on the return value of <code>getElts</code> invokes UB</p>