svn commit: r187693 - head/sys/kern

Christoph Mallon christoph.mallon at gmx.de
Sun Jan 25 11:44:38 PST 2009


Jeff Roberson schrieb:
> On Sun, 25 Jan 2009, Christoph Mallon wrote:
> 
>> Jeff Roberson schrieb:
>>> On Sun, 25 Jan 2009, Jeff Roberson wrote:
>>>
>>>> Author: jeff
>>>> Date: Sun Jan 25 18:38:42 2009
>>>> New Revision: 187693
>>>> URL: http://svn.freebsd.org/changeset/base/187693
>>>>
>>>> Log:
>>>>   - bit has to be fd_mask to work properly on 64bit platforms.  
>>>> Constants
>>>>     must also be cast even though the result ultimately is promoted
>>>>     to 64bit.
>>>>   - Correct a loop index upper bound in selscan().
>>>
>>> Sorry about that, should've tested my earlier patch for more than a 
>>> couple of days.  I seldom remember c's integer promotion rules as 
>>> they relate to constants.  You'd think they'd make it easy on us and 
>>> just promote it to the largest type in the expression/lvalue.  I'm 
>>> not sure why they don't. Perhaps the more careful among you knows the 
>>> answer.
>>
>> The rule for operations is quite simple: An operation never cares for 
>> the type of its user. It only uses the type of the operand(s) to 
>> determine its result type. So for a = b + c the type of the result of 
>> + only depends on the types of b and c, but never on a.
>> Integer literals have a bit ugly rules what type they are: It depends 
>> on the base (!) and on the magnitude of the literal.
>> If in doubt and you need a specific type (and maybe making it more 
>> clear for a reader) then cast.
>>
> 
> I'm familiar with the rule, what I don't know is the rationale.  It 
> would've been much more convenient if they did care for the user.

Well, the only rationale which really matters in the end is that it 
always was this way and therefore it cannot be changed anymore, because 
there are billions and billions of lines of code out there.

The technical reason probably was that it makes type analysis easier in 
the compiler: You only have to propagate type information from the 
leaves of an expression twoards the root instead of having to do so in 
both directions.

> In what case does the base matter?  If you use a literal large enough 
> the compiler conveniently complains.  However, in this case the shift 
> value was computed and applied to 1 which overflowed before being 
> assigned to a 64bit value.

Decimal literals which do not have a "U" as part of the suffix are 
always of a signed integer type. In contrast octal and hexadecimal 
literals can be of unsigned integer types, too.
Example: (assuming 32bit int and long, 64bit long long)
   0xFFFFFFFF is unsigned int
but
   4294967295 is signed long long int
The exact rules can be found in ISO/IEC 9899:1999(E) §6.4.4.1.

Btw: There are no negative literals. This is always a unary minus 
operator followed by a (non-negative) integer literal. This leads to one 
interesting edge case on two complement machines: the number -2147483648 
fits into a signed int. But it is parsed as unary minus operator with a 
integer literal as operand. The integer literal is too large for int, so 
its type is signed long long int. Therefore -2147483648 is of type 
signed long long int instead of the expected int. This artifact is 
mostly harmless though.


More information about the svn-src-head mailing list