svn commit: r187693 - head/sys/kern
jroberson at jroberson.net
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: http://svn.freebsd.org/changeset/base/187693
>>>>> - bit has to be fd_mask to work properly on 64bit platforms.
>>>>> 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
> 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
> 4294967295 is signed long long int
> The exact rules can be found in ISO/IEC 9899:1999(E) §22.214.171.124.
> 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