lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Brian Weed wrote:
> Jerome Vuarand wrote:
[...]
>> % make test
>> % test
>> 0x7fffffff
>> 0xffffffff
[...]
> I get different results in VS2005...
> 
> 0xffffffff
> 0xffffffff

You know, I've just had a horrible thought.

Does the C standard even *allow* you to cast an unsigned int to an int if the
value won't fit? Doesn't the result depend on your sign representation?
(0xFFFFFFFF == -1 only on two's-complement machines.) Are we seeing the
dreaded 'undefined behaviour'?

[rummages through the 'net]

Yes, I was right. This is from WG14 N1124, which is a reasonably current C99.

http://www.open-std.org/jtc1/sc22/wg14/www/standards

┄┄┄┄┄

6.3.1.3 Signed and unsigned integers

¶1 When a value with integer type is converted to another integer type other
than _Bool, if the value can be represented by the new type, it is unchanged.
¶2 Otherwise, if the new type is unsigned, the value is converted by
repeatedly adding or subtracting one more than the maximum value that can be
represented in the new type until the value is in the range of the new type.
¶3 Otherwise, the new type is signed and the value cannot be represented in
it; either the result is implementation-defined or an implementation-defined
signal is raised.

6.3.1.4 Real floating and integer

¶1 When a finite value of real floating type is converted to an integer type
other than _Bool, the fractional part is discarded (i.e., the value is
truncated toward zero). If the value of the integral part cannot be
represented by the integer type, the behavior is undefined.)
¶2 When a value of integer type is converted to a real floating type, if the
value being converted can be represented exactly in the new type, it is
unchanged. If the value being converted is in the range of values that can be
represented but cannot be represented exactly, the result is either the
nearest higher or nearest lower representable value, chosen in an
implementation-defined manner. If the value being converted is outside the
range of values that can be represented, the behavior is undefined.

┄┄┄┄┄

Therefore, casting (double)0xFFFFFFFF to an unsigned int is valid, but it's
*not* valid to cast it to an int. Casting it to an unsigned int and *then* to
an int is valid, and will result in 0xFFFFFFF.

Anything else invoces undefined behaviour, and results in daemons flying out
of your nose.

-- 
╭─┈David Given┈──McQ─╮ "...electrons, nuclei and other particles are good
│┈ dg@cowlark.com┈┈┈┈│ approximations to perfectly elastic spherical
│┈(dg@tao-group.com)┈│ cows." --- David M. Palmer on r.a.sf.c
╰─┈www.cowlark.com┈──╯

Attachment: signature.asc
Description: OpenPGP digital signature