Immoral bugs

dimitrov at csd2.UUCP dimitrov at csd2.UUCP
Sat Feb 1 10:09:00 AEST 1986


[]
I thought I'd point out a couple of minor bugs in the fast "immoral"
routines that were just posted, just in case anyone plans on actually
using them (I apologize if these are too obvious). First in the fast
version of calloc:

> /* calloc - allocate and clear memory block */
> #define CHARPERINT (sizeof(int)/sizeof(char))
> #define NULL 0
> 
> char *calloc(num, size)
> unsigned num, size;
>     {
>     register char *mp;
>     char *malloc();
>     register int *q, *qlim, m;
> 
>     num *= size;
>     mp = malloc(num);
>     if (mp == NULL) return (NULL);
>     q = (int *) mp;
>     qlim = (m = (num+CHARPERINT-1)/CHARPERINT) + (q = (int *)mp);
> 
>     switch (m & 7)
> 	do	{
> 		    *q++ = 0;
> 	    case 7: *q++ = 0;
> 	    case 6: *q++ = 0;
> 	    case 5: *q++ = 0;
> 	    case 4: *q++ = 0;
> 	    case 3: *q++ = 0;
> 	    case 2: *q++ = 0;
> 	    case 1: *q++ = 0;
> 	    case 0: ;
> 	    } while (q < qlim);
> 
>     return (mp);
>     }

I think it would be safer to substitute for the first five lines of code:

	m = ((num*size)+CHARPERINT-1)/CHARPERINT;
	mp = malloc(m*CHARPERINT);
	if (mp==NULL) return NULL;
	q = (int *)mp;
	qlim = q+m;

The point is that the loop sets m*CHARPERINT bytes to 0,
so you should make sure you malloc this many bytes or you
might go past the end of the memory you malloc. The malloc's
I've seen return values on word boundaries and in this case
it doesn't make a difference, but the code above seems safer
in general. For the second routine:

> send(to, from, count)
> register short *to, *from;
> register count;
> {
> 	register n=(count+7)/8;
> 	switch(count%8){
> 	case 0:	do{	*to = *from++;
> 	case 7:		*to = *from++;
> 	case 6:		*to = *from++;
> 	case 5:		*to = *from++;
> 	case 4:		*to = *from++;
> 	case 3:		*to = *from++;
> 	case 2:		*to = *from++;
> 	case 1:		*to = *from++;
> 		}while(--n>0);
> 	}
> }

The "case 0:" should of course be moved from the line:
> 	case 0:	do{	*to = *from++;

down to the line:
> 		}while(--n>0);

so that the two lines read:
> 	do{		*to = *from++;
>	...
> 	case 0:	}while(--n>0);

I've racked my brains for a less obscure way to write this and get
the same effect. The best I could come up with is:

send(to, from, count)
register short *to, *from;
register count;
{
	register n;

	for (; (count&7)!=0; count--)
		*to = *from++;
	for (n=count/8; n>0; n--) {
		*to=*from++; *to=*from++; *to=*from++; *to=*from++;
		*to=*from++; *to=*from++; *to=*from++; *to=*from++;
	}
}

Isaac Dimitrovsky
allegra!cmcl2!csd2!dimitrov   (l in cmcl2 is letter l not number 1)
251 Mercer Street, New York NY 10012     (212) 674-8652

You know the great thing about tv? If something important happens anywhere at
all in the world, no matter what time of the day or night, you can always
change the channel - Jim Ignatowski



More information about the Comp.lang.c mailing list