[comp.lang.c] preventing sign extension

mackenzi@thor.stolaf.edu (David MacKenzie) (01/10/89)

Now that my confusion about varargs has been taken care of, I have run
into another problem with "my" port of Holub's integer doprnt to Unix
(it's getting to be a group project . . .).

Here are some code fragments:

/*
 * INTMASK is a portable way to mask off the bottom N bits
 * of a long, where N is the width of an int.
 */
#define INTMASK	(long) ((unsigned) (0))
	:
	:
long lnum;			/* used to hold numeric arguments */
	:
	:
	/* Fetch a long or int sized argument off the
	 * stack as appropriate.  If the fetched number
	 * is a base 10 int then mask off the top
	 * bits to prevent sign extension.
	 */
	:
	:
	[skip to where it gets an int sized argument]
	lnum = (long) va_arg (args, int);
	:
	:
	[if (print in unsigned format)]
		lnum &= INTMASK;

I'm not quite sure what this was supposed to do, but on my 68000 box
with Green Hills C, it does what it looks like it's doing: a bitwise
AND with zero.  The result is that
	printf ("%d\n", 4);
produces the correct output, but
	printf ("%u\n", 4);
displays 0.

I'm a bit fuzzy on the conditions under which sign extension takes
place; I had hoped I'd never have to deal with it.  Would any of
you C wizards like to explain what Allen was trying to do, and
why it presumably works under MS-DOS but doesn't under Unix?  And
how to make it work under Unix?

David MacKenzie
edf@rocky2.rockefeller.edu

mackenzi@thor.stolaf.edu (David MacKenzie) (01/11/89)

Chris Torek has pointed out that the listing in DDJ is probably
missing a tilde, and thus that
>#define INTMASK	(long) ((unsigned) (0))
should be
>#define INTMASK	(long) ((unsigned) (~0))
and that seems right to me.  Thanks, Chris.

David MacKenzie
edf@rocky2.rockefeller.edu

gwyn@smoke.BRL.MIL (Doug Gwyn ) (01/11/89)

In article <905@thor.stolaf.edu> edf@rocky2.rockefeller.edu writes:
>#define INTMASK	(long) ((unsigned) (0))

Almost certainly this was supposed to be
 #define INTMASK	((long)(unsigned)~0)

The form you gave should not have worked on ANY C compiler.
Are you reading that from a magazine listing?  They're
notorious for goofing up "funny" symbols like ~, `, and \.