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