Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!rutgers!tut.cis.ohio-state.edu!ucbvax!ji.Berkeley.EDU!wilson From: wilson@ji.Berkeley.EDU (James E. Wilson) Newsgroups: comp.sys.mac.programmer Subject: Re: LSC 3 bug with hex constant handling? Summary: LSC is correct Keywords: Lightspeed C Message-ID: <29626@ucbvax.BERKELEY.EDU> Date: 12 Jun 89 18:12:10 GMT References: <861@key.COM> <16783@bellcore.bellcore.com> Sender: usenet@ucbvax.BERKELEY.EDU Reply-To: wilson@ji.Berkeley.EDU.UUCP (James E. Wilson) Organization: University of California, Berkeley Lines: 53 In article <16783@bellcore.bellcore.com> sdh@wind.UUCP (Stephen D Hawley) writes: >In article <861@key.COM> perry@arkon.key.COM (Perry The Cynic) writes: >>This clears the least significant bit of b. It works just fine. However, >>if I replace the "1" with its hex equivalent, i.e. >> a = b & ~0x1; >>then the resulting code uses the constant 0x0000FFFE (rather than 0xFFFFFFFE) >>as operand to the "&" operator, resulting in less than satisfactory results. > >From K&R: >"A sequence of digits preceded by 0x or 0X (digit zero) is taken to be a >hexadecimal integer. ... A decimal constant whose value exceeds the largest >unsigned machine integer is taken to be a long; an octal or hex constant which >exceeds the largest unsigned machine integer is likewise taken to be long." > >This means that the constant is correct as an int, but section 7.8 claims that >& uses the usual arithmetic conversions. In this case, it should be converted >to a long (section 6.6). > >I would say this is a bug. You missed the point of the above quote from K&R (section 2.4.1). Decimal constants are signed integers, but hexadecimal and octal constants are unsigned integers. Hence, the result of the expression ~0x1 is the unsigned integer value 0xFFFE. You are correct, that this value is then converted to a long via the usual arithmetic conversions before it is bitwise anded with b. However, according to K&R (section 6.5), unsigned values are padded on the left with zeros when they are converted to long. Hence, the result of ~0x1 after conversion to long is 0x0000FFFE. Thus, the behaviour of LSC, although rather surprising, is technically correct. For another example, consider the following code fragment (and assume that ints are 16 bits and longs are 32 bits): long a, b; a = b & 0xFFFF; Clearly, the intent is to store the lower 16 bits of b into a. And this is exactly what LSC will do. If, however, you insist that hexadecimal constants should be sign extended, then the result would be that all 32 bits of b are copied into a (since 0xFFFF is first stored as the int -1, then converted to the long value -1), which is definately not what the programmer intended. Hence, in order for the second code example to work correctly in LSC, the first code example must give a result contrary to what the naive programmer expects. These subtleties can all be ignored by just remembering to tack on a 'L' to all constants that are used with long integers. Jim Wilson wilson@ernie.Berkeley.EDU ...!ucbvax!ucbernie!wilson Ya nadeyus', chto kogda-nibud' budet mir na zemle.