[comp.sys.mac.programmer] MPW C 3.1 vs 3.0

allanh@netcom.UUCP (Allan N. Hessenflow) (05/09/90)

I recently recompiled an old program which worked fine with MPW C 3.0; it broke
with MPW C 3.1.  I discovered that the problem was a bug in my code which
got by because of a bug in C 3.0 (at least I think it's a bug; I'm not certain
how the language behavior is defined in this case).  This change doesn't seem
to be documented in the C 3.1 release notes.  I had something like:

long count;
...
if (count < 0xf0000000L) {
...

count should have been an 'unsigned long'.  With C 3.0, if count was, say, 1,
the test was true (it did an unsigned comparison for some reason), while with
C 3.1 it's false.


-- 
Allan N. Hessenflow   {apple|claris}!netcom!allanh    allanh@netcom.uucp

jholt@pro-sol.cts.com (joe holt) (05/10/90)

In-Reply-To: message from allanh@netcom.UUCP

The way I read K&R, it sounds like MPW 3.0 did things the right way.  ANSI C
says that if a hexadecimal constant is suffixed with 'l' or 'L', then its type
is long int or unsigned long int.  The compiler is supposed to try to fit the
constant into long int first, then unsigned long int if it doesn't fit.  The
constant 0xF0000000L would not fit into a long int, and so its type becomes
unsigned long int (it is legal to have the constant -0x7FFFFFFF, for example).

ANSI C also says you can stick a 'u' or 'U' suffix to force the integer
constant unsigned.

To be safe, I'd stay away from depending on the sign of ambiguous integer
constants.  Until everyone adopts ANSI C, it's going to be a compiler
dependency.

joe holt

allanh@netcom.UUCP (Allan N. Hessenflow) (05/10/90)

In article <2597@crash.cts.com>, jholt@pro-sol.cts.com (joe holt) writes:
> In-Reply-To: message from allanh@netcom.UUCP
> 
> The way I read K&R, it sounds like MPW 3.0 did things the right way.  ANSI C
> says that if a hexadecimal constant is suffixed with 'l' or 'L', then its type
> is long int or unsigned long int.  The compiler is supposed to try to fit the
> constant into long int first, then unsigned long int if it doesn't fit.  The
> constant 0xF0000000L would not fit into a long int, and so its type becomes
> unsigned long int (it is legal to have the constant -0x7FFFFFFF, for example).

I believe both versions of the C compiler interpreted the constant as an
unsigned long.  It's what they did with the long variable in the expression
that differs.  In v3.0, it apparently cast it as an unsigned.  In v3.1, it
didn't and so the comparison 'count<0xf0000000L' was always true.  I haven't
looked at the generated code, but I assume the v3.1 compiler figured out
that the test would be always true.  I don't see any other way it could
have generated a test for that expression since it doesn't have any ints
larger than 32 bits it could have cast them to.  Actually, it doesn't seem
very likely it would do that; I think I'll go look at the code it generated.


-- 
Allan N. Hessenflow   {apple|claris}!netcom!allanh    allanh@netcom.uucp