A quick question

Wayne Throop throopw at sheol.UUCP
Mon Mar 18 10:54:04 AEST 1991


> eychaner at suncub.bbso.caltech.edu (Amateurgrammer)
> int do_array (void *array, int size, int type)
> {
> unsigned char *arrayptr;
> int i;
> 
> arrayptr = array;   /* If only void * arithmetic were legal in VAX C */
> for (i = 0; i < size; i++) {
>     if (type == UNSIGNED_CHAR) {
>         /* My precedence rules say this is right */
>         *arrayptr++ = some_value();  /* Declared properly elsewhere */
>         }
>     else if (type == SHORT) {
>         /* My precedence rules ALSO say THIS is right */
>         *(short *)arrayptr++ = othervalue();  /* Declared elsewhere */
>         }
>     }
> }

Since what is wanted is a "generic" routine to operate on arrays of
integers of various types (and since the common "wrapping" of this
operation is large enough to want to commonize in a single routine),
I'd try to make the binding of the void to specific type as localized
and clear as possible.  Tweaking the above example, I'd suggest:

int do_array (void *formal_array, int size, int type) {
    int i;
    unsigned char *uchar_array = (unsigned char*)formal_array;
    short *short_array = (short*)formal_array;
    for (i = 0; i < size; i++) {
        if (type == UNSIGNED_CHAR)
            uc_array[i] = some_value();
        else if (type == SHORT) 
            short_array[i] = othervalue();
    }
}

Further, if the persistence of the two "interpretations" of the
"generic" argument didn't need to interpenetrate to make the loop
control common, I'd segregate them, so that errors involving using the
wrong interpretation of the formal would be less likely.  For example:

int do_array (void *formal_array, int size, int type) {
    int i;
    if (type == UNSIGNED_CHAR) {
        unsigned char *array = (unsigned char*)formal_array;
        for (i = 0; i < size; i++)
            array[i] = some_value();
    }
    else if (type == SHORT) {
        short *array = (short*)formal_array;
        for (i = 0; i < size; i++)
            array[i] = othervalue();
    }
}

There are further tricks that can be played with macros and so on
(and more cleanly with by-name bindings in other languages), but
in C these alternatives are mostly pretty disgusting in all but
trivial examples.
--
Wayne Throop  ...!mcnc!dg-rtp!sheol!throopw



More information about the Comp.lang.c mailing list