T
tho
Hello,
we'd like to create a simple dynamic array library which is type-
agnostic with respect to the elements (both scalar and aggregate/union
types) that the user interface needs to set/get.
A possible approach that we're considering is to brutally alias a type
to its underlying size (as returned by the sizeof operator) and
handling element input/output via void* pointers, like this:
struct darray_s
{
size_t esize; /* size of each array element */
char *elems; /* base pointer */
};
int darray_create(size_t esize, darray_t **pda);
/* 'i' is the index at which 'elem' shall be set/get */
int darray_set(darray_t *da, size_t i, void *elem);
int darray_get(darray_t *da, size_t i, void **ptr);
Now the implementation.
int darray_set(darray_t *da, size_t i, void *elem)
{
...
memcpy(da->elems + (i * da->esize), elem, da->esize);
...
}
The pointer arithmetic in the setter method should be correct: we have
a char* base whose offset is computed in multiples of the given
element size. Once the slot is located, we do a raw memory copy of
the required size.
int darray_get(darray_t *da, size_t i, void **ptr)
{
...
*ptr = da->elems + (i * da->esize);
...
}
On the other hand, in the getter method we are doing an assignement
from char* to void*, which implies an implicit conversion since we
can't do explicit casts for obvious reasons. Another conversion is
carried out implicitly while passing the 'ptr' parameter to the
darray_get() in order to close the chain my_t* <-> void* <-> char*
from the caller to the implementation through the interface and
viceversa.
So, the question is: could the implicit conversion cause any
alteration in the pointers used to handle darray input/output ? And
more generally do you see any other problem here that we may have
overlooked ?
Thanks in advance, t.
we'd like to create a simple dynamic array library which is type-
agnostic with respect to the elements (both scalar and aggregate/union
types) that the user interface needs to set/get.
A possible approach that we're considering is to brutally alias a type
to its underlying size (as returned by the sizeof operator) and
handling element input/output via void* pointers, like this:
struct darray_s
{
size_t esize; /* size of each array element */
char *elems; /* base pointer */
};
int darray_create(size_t esize, darray_t **pda);
/* 'i' is the index at which 'elem' shall be set/get */
int darray_set(darray_t *da, size_t i, void *elem);
int darray_get(darray_t *da, size_t i, void **ptr);
Now the implementation.
int darray_set(darray_t *da, size_t i, void *elem)
{
...
memcpy(da->elems + (i * da->esize), elem, da->esize);
...
}
The pointer arithmetic in the setter method should be correct: we have
a char* base whose offset is computed in multiples of the given
element size. Once the slot is located, we do a raw memory copy of
the required size.
int darray_get(darray_t *da, size_t i, void **ptr)
{
...
*ptr = da->elems + (i * da->esize);
...
}
On the other hand, in the getter method we are doing an assignement
from char* to void*, which implies an implicit conversion since we
can't do explicit casts for obvious reasons. Another conversion is
carried out implicitly while passing the 'ptr' parameter to the
darray_get() in order to close the chain my_t* <-> void* <-> char*
from the caller to the implementation through the interface and
viceversa.
So, the question is: could the implicit conversion cause any
alteration in the pointers used to handle darray input/output ? And
more generally do you see any other problem here that we may have
overlooked ?
Thanks in advance, t.