unsigned int 2 ulong type promotion issue in GCC!

Thamilarasu Kandasamy (thamil) thamil@cisco.com
Tue May 26 10:16:45 GMT 2020


Thanks Jonathan, that helps!

Thanks
Thamil

On 26/05/20, 2:24 PM, "Jonathan Wakely" <jwakely.gcc@gmail.com> wrote:

    On Tue, 26 May 2020 at 04:34, Thamilarasu Kandasamy (thamil) via
    Gcc-help <gcc-help@gcc.gnu.org> wrote:
    >
    > Hi
    >
    > I could deduce what is happening based on the output of the program.
    >
    > I am looking for an affirmative answer which explains because of this type promotion rule involving unsigned long and unsigned int, promotion of low rank type to high rank type doesn't happen, please quote that rule.
    >
    > As per my understanding, type promotion from unsigned int to unsigned long int should have happened. But it doesn't,

    Yes it does. But promoting (unsigned)0x123 to unsigned long will
    promote 0x00000123 to 0x0000000000000123, which you seem to think
    means it is not promoted. It is promoted, but the value doesn't
    change, and the high bits are all zero.

    > hence I am trying to know which type promotion rules apply here,  is it documented anywhere ?

    In the C standard, of course. You might also find
    https://en.wikipedia.org/wiki/Sign_extension useful. GCC does exactly
    what it's supposed to.

    Maybe https://cppinsights.io/s/7375972e will help you understand which
    promotions happen at which points.

    ~(size - 1) is a 32-bit int with a negative value. When it gets
    promoted to 64-bits the value gets "sign extended" to produce a 64-bit
    unsigned value that has the same bit pattern as (signed long)-99. In
    hex (int)0xffffff9d gets promoted to (unsigned
    long)0xffffffffffffff9d.

    ~(usize - 1) is a 32-bit unsigned int (with a positive value, of
    course, because it's unsigned). It gets promoted from
    (unsigned)0xffffff9d to (unsigned long)0x000000000xffffff9d. When you
    AND that with the pointer value, obviously half the bits of the
    pointer will be lost.

    ~((unsigned long)usize - 1) is a 64-bit unsigned int, so no promotion
    happens. But in this case the value is already 64-bits before the ~
    operation, so you get ~(0x0000000000000064 - 1) which is
    ~0x0000000000000063 which is 0xffffffffffffff9c.

    GCC is doing the right thing, you're just not understanding what the
    right thing is.



More information about the Gcc-help mailing list