svn commit: r187693 - head/sys/kern

Jeff Roberson jroberson at
Sun Jan 25 11:57:31 PST 2009

On Sun, 25 Jan 2009, Christoph Mallon wrote:

> 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:
>>>>> 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.

This is a good point.  Since most of C seems to have been designed with 
the convenience of the compiler writer in mind it's probably the right 


>> 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) §
> 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