[comp.lang.c] How come << falls through at 16 on a 32-bit integer?

markh@csd4.csd.uwm.edu (Mark William Hopkins) (04/13/91)

Why am I getting 0 for output here when unsigned long's are 32 bits with the
Quick C Version 2.5 compiler?  (Casting everything to unsigned long does not
help).

* #include <stdio.h>
* main() {
*    unsigned long M = 34;
*    printf("%08x\n", M << 16);
* }

This is a compiler bug, according to my understanding of the Quick C manual
and C language.

grogers@convex.com (Geoffrey Rogers) (04/13/91)

In article <11004@uwm.edu> markh@csd4.csd.uwm.edu (Mark William Hopkins) writes:
>* #include <stdio.h>
>* main() {
>*    unsigned long M = 34;
>*    printf("%08x\n", M << 16);
>* }

No. The problem is the %08x expects an int and you are printing a long
(unsigned long). You must also use the l flag to tell printf that the
argument is a long. Try:

	printf("%08lx\n", M << 16)


+------------------------------------+---------------------------------+
| Geoffrey C. Rogers   		     | "Whose brain did you get?"      |
| grogers@convex.com                 | "Abbie Normal!"                 |
| {sun,uunet,uiucdcs}!convex!grogers |                                 |
+------------------------------------+---------------------------------+

scs@adam.mit.edu (Steve Summit) (04/14/91)

In article <11004@uwm.edu> markh@csd4.csd.uwm.edu (Mark William Hopkins) writes:
> Why am I getting 0 for output here when unsigned long's are 32 bits with the
> Quick C Version 2.5 compiler?
> *    unsigned long M = 34;
> *    printf("%08x\n", M << 16);

The short answer, which we'll be seeing numerous repetitions of
over the next few days, is that M << 16, being a long, must be
printed with %lx (or, of course, %08lx in this example).

I've noticed that this question has been much more frequent since
ANSI-style function prototypes started coming into widespread
use.  Prototypes are not a crutch (though it's easy and tempting
to use them as one); it's important to understand that prototypes
do not take care of the types of all function call arguments
everywhere, and that the programmer must therefore remember to
think about argument type when required.  In particular,
prototypes never act on the variable arguments in a variable-
length argument list, such as the arguments following the format
string of a printf-style function.

(It has always been easy to forget that the printf format string
is virtually always interpreted only at run-time, and that the
programmer is therefore responsible for carefully matching
argument types to %-format specifiers.  Some versions of lint
will do a static check of printf arguments and format strings, as
long as the format strings are simple compile-time constants, as
they usually are.)

> This is a compiler bug, according to my understanding of the Quick C manual
> and C language.

Not to criticize you, but any time *anyone's* understanding of
the language doesn't match the behavior of the compiler, prompting
a cry of "compiler bug!", it's usually the "understanding" that's
at fault.  (Sadly, compilers do occasionally have bugs, so a rule
like "always believe the compiler" must not be applied religiously.
As learn(1) sagely points out, "Occasionally lessons are incorrect...
Such lessons may be skipped with the `skip' command, but it takes
some sophistication to recognize the situation.")

                                            Steve Summit
                                            scs@adam.mit.edu

wirzenius@cc.helsinki.fi (Lars Wirzenius) (04/14/91)

In article <11004@uwm.edu>, markh@csd4.csd.uwm.edu (Mark William Hopkins) writes:
> Why am I getting 0 for output here when unsigned long's are 32 bits with the
> *    unsigned long M = 34;
> *    printf("%08x\n", M << 16);

It's because the x format specifier means the argument is of size int,
not long.  Use lx instead. 

-- 
Lars Wirzenius    wirzenius@cc.helsinki.fi

markh@csd4.csd.uwm.edu (Mark William Hopkins) (04/15/91)

In article <1991Apr14.003724.8979@athena.mit.edu> scs@adam.mit.edu writes:
>Not to criticize you, but any time *anyone's* understanding of
>the language doesn't match the behavior of the compiler, prompting
>a cry of "compiler bug!", it's usually the "understanding" that's
>at fault...

Different people have different experiences.  In my case, I am right about
90% of the time, and the compiler (or hardware) only about 10%.