Re: Some questions on c99, gcc, and multi-dimensional dynamic arrays

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Cedric,

> I have a hard time trying to figure out if the following code works as
> expected on every platforms available today.
>
> I want to make a function that creates a multi-dimensional array of a
> given type.  The function has to be generic.
>
> A simple solution is to allocate an array of the wanted size for the
> base type and another array that we fill with pointers, so we can
> write: array[i][j][k][l][m] = xx;
>
> As you can see array[i] has not the same type as array[i][j]. This is
> the problem I face.

well, for sure I'm not an expert, but just my 2 cents:
> So, are there platforms out there where different pointers' types are
> indeed different, so that you can't use the address of a double * to
> point to an int? I know there are alignment issues, but apart from
> that? Are there some pointers that are, I don't know, 32 bits for a
> double * and 48 bits or whatever for an int *?
 - the memory-allocation-functions  (calloc, malloc, ...) all return
   pointers of type "void *", which you then can convert to all pointer
   types:
     double *d = malloc(size);
     int *i = malloc(size);
   are both valid  - and malloc has no informations how I'm going to use
   the returned pointer (as int* or double* or ...) - it just knows the
   total size of memory I want to allocate. So converting "void *" to an
   arbitrary pointer type seems to work under all circumstances (apart
   alignment problems ...). And your "proposal" (32 bits for double* and
   48 Bits for int*) can't be true - all pointers have to have the same
   size.

 - The standard says (6.3.2.3.1) "A pointer to any incomplete or object
   type may be converted to a pointer to void and back again; the result
   shall compare equal to the original pointer."
   As I understand that, it should be no problem to convert an arbitrary
   pointer to void * and then convert it back to original type and use
   it.

> So we treat every pointers in the pointers' array as "void *" and we
> pretend that "void *" is like "void **" and like "void ***" and so on. 
 - as "void **" is just a pointer to "a pointer to an element of type
   void", I think that also this conversion (from this pointer type to
   "void *" and back) should be no problem.

> And also like "base_type *" which we don't know but simply pass its
> size to make_matrix as sizeof(base_type).
 - malloc does never know anything about the type for which you allocate
   the memory - so it is impossible that this information is necessary
   to allocate memory and return a pointer to it correctly. Just knowing
   the size of the element (when using calloc) or the total memory size
   needed (when using malloc) is sufficient to create a correctly usable
   pointer.

The only danger I see is - as you mentioned - the alignment: "void
*"-pointers are aligned as "char *" (6.2.5.26). If you convert a pointer
to void*, shift it by an integer and convert it back to the original
type, YOU are responsible for the correct alignment.

So, I suppose it should be working correctly on all platforms. But let's
see what the true gcc-experts say:-)

Axel


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux