Constants: when to use L U UL ....

Discussion in 'C Programming' started by luke, Sep 21, 2005.

  1. luke

    luke Guest

    Hi,
    I know that the suffixes L U UL mean that the constant has to be
    treated as long, unsigned,... but I didn't know when to use it and when
    not.
    thanks

    luke
     
    luke, Sep 21, 2005
    #1
    1. Advertising

  2. "luke" <> wrote in message
    news:...
    > Hi,
    > I know that the suffixes L U UL mean that the constant has to be
    > treated as long, unsigned,... but I didn't know when to use it and when
    > not.
    > thanks


    A few examples:

    1. long x = 0xFFFF;
    2. int a=10000; long c = a*4;

    1.: On a 16-bit system (int is 16-bit long) you'll get x=-1, while on 32-bit
    one you'll get x=65535... The fix is to write 0xFFFFU or 0xFFFFUL.
    2.: On a 16-bit system you'll get an overflow in multiplication and hence
    wrong value in c (less than 32768), while on 32-bit the result will be OK.
    The fix is to cast either of multipliers to long or to turn 4 into 4L.

    Alex
     
    Alexei A. Frounze, Sep 21, 2005
    #2
    1. Advertising

  3. luke

    Jirka Klaue Guest

    Alexei A. Frounze:

    > 1. long x = 0xFFFF;
    > 2. int a=10000; long c = a*4;
    >
    > 1.: On a 16-bit system (int is 16-bit long) you'll get x=-1


    I don't think so. Since 0xffff is in the range of unsigned int on
    a 16-bit-int system, you should get 65535.

    Jirka
     
    Jirka Klaue, Sep 21, 2005
    #3
  4. luke

    Eric Sosman Guest

    Alexei A. Frounze wrote:

    > "luke" <> wrote in message
    > news:...
    >
    >>Hi,
    >>I know that the suffixes L U UL mean that the constant has to be
    >>treated as long, unsigned,... but I didn't know when to use it and when
    >>not.
    >>thanks

    >
    >
    > A few examples:
    >
    > 1. long x = 0xFFFF;
    > 2. int a=10000; long c = a*4;
    >
    > 1.: On a 16-bit system (int is 16-bit long) you'll get x=-1, while on 32-bit
    > one you'll get x=65535... The fix is to write 0xFFFFU or 0xFFFFUL.


    No, x will be 65535 on all conforming C implementations.
    On a system with 16-bit int, 0xFFFF is an unsigned int constant
    with the value 65535u. On a system with wider int, 0xFFFF is
    an int constant with the value 65535. Either way, x is initialized
    with the value 65535(u), converted to long. See 6.4.4.1/5.

    > 2.: On a 16-bit system you'll get an overflow in multiplication and hence
    > wrong value in c (less than 32768), while on 32-bit the result will be OK.
    > The fix is to cast either of multipliers to long or to turn 4 into 4L.


    You're right about the overflow, but wrong about the
    result: the behavior is undefined, and there is no guarantee
    that any value (wright or rong) will be produced. The suggested
    fix is correct.

    --
    Eric Sosman
    lid
     
    Eric Sosman, Sep 21, 2005
    #4
  5. luke

    luke Guest

    thanx for the answer, but I didn't understand why "long x = 0xFFFF"
    produces -1
    a long is 32 bit even on 16-bit systems, isn't it? so you get 65535
    anyway
     
    luke, Sep 21, 2005
    #5
  6. "Eric Sosman" <> wrote in message
    news:...
    > Alexei A. Frounze wrote:
    > > 1. long x = 0xFFFF;
    > > 2. int a=10000; long c = a*4;
    > >
    > > 1.: On a 16-bit system (int is 16-bit long) you'll get x=-1, while on

    32-bit
    > > one you'll get x=65535... The fix is to write 0xFFFFU or 0xFFFFUL.

    >
    > No, x will be 65535 on all conforming C implementations.
    > On a system with 16-bit int, 0xFFFF is an unsigned int constant
    > with the value 65535u. On a system with wider int, 0xFFFF is
    > an int constant with the value 65535. Either way, x is initialized
    > with the value 65535(u), converted to long. See 6.4.4.1/5.


    OK, I was wrong. But I remember I had some problem with this or something
    very similar... But maybe it was a bit different thing (signed to unsigned
    conversion), though...
    Sorry.

    > > 2.: On a 16-bit system you'll get an overflow in multiplication and

    hence
    > > wrong value in c (less than 32768), while on 32-bit the result will be

    OK.
    > > The fix is to cast either of multipliers to long or to turn 4 into 4L.

    >
    > You're right about the overflow, but wrong about the
    > result: the behavior is undefined, and there is no guarantee
    > that any value (wright or rong) will be produced. The suggested
    > fix is correct.


    You're right about the UB (as prescribed by the standard), though it's more
    likely to get this problem w/o any side effects other than just a wrong
    value. Actually, I'd probably prefer to get an exception as form of this UB
    to locate the problematic place in the code.

    Alex
     
    Alexei A. Frounze, Sep 21, 2005
    #6
  7. On Wed, 21 Sep 2005 06:01:23 -0700, luke wrote:

    > thanx for the answer, but I didn't understand why "long x = 0xFFFF"
    > produces -1


    It doesn't.

    > a long is 32 bit even on 16-bit systems, isn't it? so you get 65535
    > anyway


    However 0xFFFF doesn't have long type, it has type int of that can
    represent 65535 or else unsigned int which is guaranteed to be able to
    represent 65535. In either case the value is then converted to long before
    being assigned.

    So the code does do the right thing i.e. x ends up with the value 65535,
    always. But there are types other than long involved. However

    long x = 0x10000;

    STILL works find and is guaranteed to give x the value 65536. If the value
    can't be represented as an unsigned int the compiler will represent it as
    a long. However there are cases where you need to force to a longer type,
    e.g. the expression

    1 << 24

    i.e. 1 left shifted 24 places is invalid on systems with, say, 16 bit
    ints. Whereas

    1L << 24

    and for many cases

    1UL << 24

    is even better because bit manipulations are best done on unsigned types.

    Lawrence
     
    Lawrence Kirby, Sep 21, 2005
    #7
  8. luke

    Eric Sosman Guest

    Alexei A. Frounze wrote On 09/21/05 10:05,:
    > "Eric Sosman" <> wrote in message
    > news:...
    >
    >>Alexei A. Frounze wrote:
    >>
    >>>1. long x = 0xFFFF;
    >>>2. int a=10000; long c = a*4;
    >>>
    >>>1.: On a 16-bit system (int is 16-bit long) you'll get x=-1, while on

    >
    > 32-bit
    >
    >>>one you'll get x=65535... The fix is to write 0xFFFFU or 0xFFFFUL.

    >>
    >> No, x will be 65535 on all conforming C implementations.
    >>On a system with 16-bit int, 0xFFFF is an unsigned int constant
    >>with the value 65535u. On a system with wider int, 0xFFFF is
    >>an int constant with the value 65535. Either way, x is initialized
    >>with the value 65535(u), converted to long. See 6.4.4.1/5.

    >
    >
    > OK, I was wrong. But I remember I had some problem with this or something
    > very similar... But maybe it was a bit different thing (signed to unsigned
    > conversion), though...
    > Sorry.


    On many 16-bit systems, `long x = (int)0xFFFF;' would
    initialize x to -1. More plausibly,

    int i = 0xFFFF;
    long x = i;

    is likely (but not guaranteed, of course) to do the same.

    >>>2.: On a 16-bit system you'll get an overflow in multiplication and

    >
    > hence
    >
    >>>wrong value in c (less than 32768), while on 32-bit the result will be

    >
    > OK.
    >
    >>>The fix is to cast either of multipliers to long or to turn 4 into 4L.

    >>
    >> You're right about the overflow, but wrong about the
    >>result: the behavior is undefined, and there is no guarantee
    >>that any value (wright or rong) will be produced. The suggested
    >>fix is correct.

    >
    >
    > You're right about the UB (as prescribed by the standard), though it's more
    > likely to get this problem w/o any side effects other than just a wrong
    > value. Actually, I'd probably prefer to get an exception as form of this UB
    > to locate the problematic place in the code.


    IIRC (it was long ago), the IBM s/360 could be operated in
    a mode that produced traps when integer arithmetic overflowed.
    I don't know whether that mode survives in its s/390 -- er,
    excuse me, "eServer zSeries" descendant.

    --
     
    Eric Sosman, Sep 21, 2005
    #8
  9. Alexei A. Frounze wrote:
    > "luke" <> wrote in message
    > news:...
    > > Hi,
    > > I know that the suffixes L U UL mean that the constant has to be
    > > treated as long, unsigned,... but I didn't know when to use it and when
    > > not.
    > > thanks

    >
    > A few examples:
    >
    > 1. long x = 0xFFFF;
    > 2. int a=10000; long c = a*4;

    <snip>

    Here you should use 4L instead of 4 as the expression a*4 is
    calculating
    using int arithmetic. If int is 16-bit, then c may not get the value
    40000.

    --
    Peter
     
    Peter Nilsson, Sep 22, 2005
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kai Grossjohann

    Use constants in Java beans?

    Kai Grossjohann, Dec 1, 2003, in forum: Java
    Replies:
    3
    Views:
    1,080
    John C. Bollinger
    Dec 2, 2003
  2. Curtis
    Replies:
    11
    Views:
    2,417
    Beauregard T. Shagnasty
    Jan 9, 2006
  3. Andrew FPGA
    Replies:
    19
    Views:
    918
    Jim Lewis
    Oct 11, 2006
  4. Replies:
    6
    Views:
    332
    Juha Nieminen
    Dec 8, 2007
  5. Bill H

    How can I use constants?

    Bill H, Jul 12, 2008, in forum: Perl Misc
    Replies:
    4
    Views:
    106
    Peter J. Holzer
    Jul 13, 2008
Loading...

Share This Page