Re: G_ARRAY_LENGTH for glib.h?



On Mon, 24 Jan 2000, Sebastian Wilhelmi wrote:

> Hi Tim,
> 
> > this is probably compiler version dependant, i did these kinds of tests
> > about 2 yers ago (and iirc tested the same code with lcc as well), also
> > have you tried compiling this code with -g?
> > remeber, gcc is not the only compiler out there ;)
> 
> Yes, and it only works, when compiled with -O1 (or more). But I think, it
> would be ok to add a test at least for gcc with optimize. Something like the
> following, thus preventing everybody with a gcc from doing such stupid
> mistakes:
> 
> /* Count the number of elements in an array. The array must be defined
>  * as such; using this with a dynamically allocated array will give
>  * incorrect results.
>  */
> #if defined(__GNUC__) && defined(__OPTIMIZE__)
> /* The following function is only declared, but never defined. If we
>  * use the gnu compiler with optimization turned on, this function is
>  * not referenced, when using G_N_ELEMENTS with arrays only. Otherwise
>  * the linking will fail. */
> int G_N_ELEMENTS_error_the_provided_object_is_not_an_array();
> #  define G_N_ELEMENTS(arr)						\
>   ((((gpointer)&(arr))!=((gpointer)&((arr)[0])))?			\
>     (G_N_ELEMENTS_error_the_provided_object_is_not_an_array()):		\
>     (sizeof(arr) / sizeof((arr)[0])))
> #else
> #  define G_N_ELEMENTS(arr)		(sizeof(arr) / sizeof((arr)[0]))
> #endif

even if this *would* work, i wouldn't put it in glib.h, simply because
1) the test is not fully reliable (try it with gpointer p = &p;)
2) the macro is provided for convenience of people so far doing
   sizeof (array) / sizeof (array[0]), and those already know
   that this kind of thing only works for arrays
3) programmers using macros should at least have a remote idea about
   what the macro is intended for (MAX as defined in glib.h doesn't
   produce sane results for MAX (y++, ++x) either)
4) your definition simply doesn't work, try compiling the following
   example:

typedef void * gpointer;
int G_N_ELEMENTS_error_the_provided_object_is_not_an_array();
#  define G_N_ELEMENTS(arr)                                             \
  ((((gpointer)&(arr))!=((gpointer)&((arr)[0])))?                       \
    (G_N_ELEMENTS_error_the_provided_object_is_not_an_array()):         \
    (sizeof(arr) / sizeof((arr)[0])))
static char as[2] = { 0, };
static int  n_as = G_N_ELEMENTS (as);

with gcc -c and figure.

> 
> Bye,
> Sebastian
> 

---
ciaoTJ



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