weird 'C' warning - can you solve this?

Discussion in 'C Programming' started by Ross, Feb 24, 2004.

  1. Ross

    Ross Guest

    I'm compiling some code over and over with no problems. The only
    differences between the versions is slightly different constants that
    are specific to various embedded devices that are getting loaded.
    Suddenly I notice a certain value generates a warning. Here's the
    low-down:

    The specific instance of the "-6" in this phrase generates a warning:

    const signed long tzerocal_A[] ={80000, 15000, -60000 }; //bad

    with some experimenting, -50000, and -40000 are also not liked


    All these other versions will compile fine
    const signed long tzerocal_A[] ={80000, 15000, -70000 }; //fine
    const signed long tzerocal_A[] ={80000, 15000, -80000 }; //fine


    a work around (I think) is to explicitly put an L in place to denote a
    long - but why that would work, who knows?

    const signed long tzerocal_A[] ={80000, 15000, -60000L }; //fine


    The warning is specifically:

    [warning] unsigned operand of unary -

    Can anyone explain why this is happening. If -60000 were beyond the
    valid range of a signed long, then surely -70000 or -80000 would
    generate a warning too.

    Thx. Ross.
    Ross, Feb 24, 2004
    #1
    1. Advertising

  2. "Ross" <> wrote in message
    news:...
    >
    > I'm compiling some code over and over with no problems. The only
    > differences between the versions is slightly different constants that
    > are specific to various embedded devices that are getting loaded.
    > Suddenly I notice a certain value generates a warning. Here's the
    > low-down:
    >
    > The specific instance of the "-6" in this phrase generates a warning:
    >
    > const signed long tzerocal_A[] ={80000, 15000, -60000 }; //bad
    >
    > with some experimenting, -50000, and -40000 are also not liked
    >
    > All these other versions will compile fine
    > const signed long tzerocal_A[] ={80000, 15000, -70000 }; //fine
    > const signed long tzerocal_A[] ={80000, 15000, -80000 }; //fine
    >
    > a work around (I think) is to explicitly put an L in place to denote a
    > long - but why that would work, who knows?
    >
    > const signed long tzerocal_A[] ={80000, 15000, -60000L }; //fine
    >
    > The warning is specifically:
    >
    > [warning] unsigned operand of unary -
    >
    > Can anyone explain why this is happening. If -60000 were beyond the
    > valid range of a signed long, then surely -70000 or -80000 would
    > generate a warning too.


    It's obvious actually. int is 16 bits wide on your system, so anything over
    32767 is considered unsigned. Appending an explicit L after the number makes
    it long. To prove that, you could try any number between 32768 and 65535
    inclusive, all of them should give you the warning. Numbers smaller or
    bigger than that would appear to be OK. The correct way is of course using
    L.

    Peter
    Peter Pichler, Feb 24, 2004
    #2
    1. Advertising

  3. Ross

    Guest

    Ross <> wrote:
    >
    > The specific instance of the "-6" in this phrase generates a warning:
    >
    > const signed long tzerocal_A[] ={80000, 15000, -60000 }; //bad

    [...]
    > [warning] unsigned operand of unary -
    >
    > Can anyone explain why this is happening.


    Because your compiler is broken. It appears to be treating unsuffixed
    decimal constants between INT_MAX and UINT_MAX as having type unsigned
    int, but the C Standard requires them to have type long int (unlike
    octal and hex constants, decimal constants are *never* interpreted as
    unsigned without an explicit u or U suffix).

    -Larry Jones

    The surgeon general should issue a warning about playing with girls. -- Calvin
    , Feb 24, 2004
    #3
  4. Ross

    Nejat AYDIN Guest

    Peter Pichler wrote:
    >
    > "Ross" <> wrote in message
    > news:...
    > >
    > > I'm compiling some code over and over with no problems. The only
    > > differences between the versions is slightly different constants that
    > > are specific to various embedded devices that are getting loaded.
    > > Suddenly I notice a certain value generates a warning. Here's the
    > > low-down:
    > >
    > > The specific instance of the "-6" in this phrase generates a warning:
    > >
    > > const signed long tzerocal_A[] ={80000, 15000, -60000 }; //bad
    > >
    > > with some experimenting, -50000, and -40000 are also not liked
    > >
    > > All these other versions will compile fine
    > > const signed long tzerocal_A[] ={80000, 15000, -70000 }; //fine
    > > const signed long tzerocal_A[] ={80000, 15000, -80000 }; //fine
    > >
    > > a work around (I think) is to explicitly put an L in place to denote a
    > > long - but why that would work, who knows?
    > >
    > > const signed long tzerocal_A[] ={80000, 15000, -60000L }; //fine
    > >
    > > The warning is specifically:
    > >
    > > [warning] unsigned operand of unary -
    > >
    > > Can anyone explain why this is happening. If -60000 were beyond the
    > > valid range of a signed long, then surely -70000 or -80000 would
    > > generate a warning too.

    >
    > It's obvious actually. int is 16 bits wide on your system, so anything over
    > 32767 is considered unsigned.


    Then the compiler is broken. The unsuffixed decimal constants over 32767 must be
    considered ``long int'' if it is less than LONG_MAX, assuming an implementation
    where INT_MAX is 32767.
    Nejat AYDIN, Feb 25, 2004
    #4
  5. wrote:
    > Ross <> wrote:
    >
    >>The specific instance of the "-6" in this phrase generates a warning:
    >>
    >>const signed long tzerocal_A[] ={80000, 15000, -60000 }; //bad

    >
    >
    >>[warning] unsigned operand of unary -
    >>
    >>Can anyone explain why this is happening.

    >
    > Because your compiler is broken. It appears to be treating unsuffixed
    > decimal constants between INT_MAX and UINT_MAX as having type unsigned
    > int, but the C Standard requires them to have type long int (unlike
    > octal and hex constants, decimal constants are *never* interpreted as
    > unsigned without an explicit u or U suffix).
    >
    > -Larry Jones


    Not quite. Before long long came along, a decimal constant higher than
    LONG_MAX would result in an unsigned long type. See 3.1.3.2 of C90.

    I agree with your diagnosis, however.

    Mark F. Haigh
    Mark F. Haigh, Feb 25, 2004
    #5
  6. Ross

    Dan Pop Guest

    In <kX__b.30076$> "Mark F. Haigh" <> writes:

    >Not quite. Before long long came along, a decimal constant higher than
    >LONG_MAX would result in an unsigned long type. See 3.1.3.2 of C90.

    ^^^^^^^^^^^^^^
    No such thing. It's 3.1.3.2 of C89. The most important contribution of
    ISO to the ANSI C standard was screwing its section numbering.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Feb 25, 2004
    #6
  7. "Nejat AYDIN" <> wrote:
    > Peter Pichler wrote:
    > > It's obvious actually. int is 16 bits wide on your system, so anything

    over
    > > 32767 is considered unsigned.

    >
    > Then the compiler is broken. The unsuffixed decimal constants over 32767

    must be
    > considered ``long int'' if it is less than LONG_MAX, assuming an

    implementation
    > where INT_MAX is 32767.


    I never said otherwise :)

    About 5 years ago, when I was working on embedded projects, such compilers
    were quite common. I don't know what the situation is now.

    ITYM assuming an implementation where INT_MAX < LONG_MAX, BTW.
    Peter Pichler, Feb 25, 2004
    #7
  8. Ross

    Dan Pop Guest

    In <> "Peter Pichler" <> writes:

    >"Nejat AYDIN" <> wrote:
    >> Peter Pichler wrote:
    >> > It's obvious actually. int is 16 bits wide on your system, so anything

    >over
    >> > 32767 is considered unsigned.

    >>
    >> Then the compiler is broken. The unsuffixed decimal constants over 32767

    >must be
    >> considered ``long int'' if it is less than LONG_MAX, assuming an

    >implementation
    >> where INT_MAX is 32767.

    >
    >I never said otherwise :)


    Then, what did you mean by:

    The correct way is of course using L.
    ^^^^^^^ ^^^^^^^^^
    What exactly is *incorrect* if L is omitted, apart from the broken
    compiler's behaviour?

    >About 5 years ago, when I was working on embedded projects, such compilers
    >were quite common. I don't know what the situation is now.
    >
    >ITYM assuming an implementation where INT_MAX < LONG_MAX, BTW.


    If int is 16-bit, which is already explicitly assumed in your original
    post, INT_MAX *must* be lower than LONG_MAX, unless the implementation
    is *severely* broken.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Feb 25, 2004
    #8
  9. "Dan Pop" <> wrote in message
    news:c1ijna$s0q$...
    > In <> "Peter Pichler"

    <> writes:
    > >"Nejat AYDIN" <> wrote:

    ....
    > >> Then the compiler is broken. The unsuffixed decimal constants over

    32767
    > >must be
    > >> considered ``long int'' if it is less than LONG_MAX, assuming an

    > >implementation
    > >> where INT_MAX is 32767.

    > >
    > >I never said otherwise :)

    >
    > Then, what did you mean by:
    >
    > The correct way is of course using L.
    > ^^^^^^^ ^^^^^^^^^


    An advice how to solve the OP's problem.

    > What exactly is *incorrect* if L is omitted, apart from the broken
    > compiler's behaviour?


    Failing to say A does not mean implying !A.

    I know how futile it is to argue with you, so I will shut up now.
    I prefer being happy to being right :)

    Peter
    Peter Pichler, Feb 26, 2004
    #9
  10. Ross

    Dan Pop Guest

    In <> "Peter Pichler" <> writes:

    >"Dan Pop" <> wrote in message
    >news:c1ijna$s0q$...
    >> In <> "Peter Pichler"

    ><> writes:
    >> >"Nejat AYDIN" <> wrote:

    >...
    >> >> Then the compiler is broken. The unsuffixed decimal constants over

    >32767
    >> >must be
    >> >> considered ``long int'' if it is less than LONG_MAX, assuming an
    >> >implementation
    >> >> where INT_MAX is 32767.
    >> >
    >> >I never said otherwise :)

    >>
    >> Then, what did you mean by:
    >>
    >> The correct way is of course using L.
    >> ^^^^^^^ ^^^^^^^^^

    >
    >An advice how to solve the OP's problem.


    It's a lot more than that. It's *also* an implication that the OP's
    way was incorrect. And a strong clue that you believed the OP's code
    to be incorrect.

    A properly phrased advice would have been something along the lines:
    "you can shut up the bogus warning by using the L suffix".

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Feb 26, 2004
    #10
  11. "Dan Pop" <> wrote in message
    news:c1lclg$qej$...
    > In <> "Peter Pichler"

    <> writes:
    > >"Dan Pop" <> wrote in message

    ....
    > >> Then, what did you mean by:
    > >>
    > >> The correct way is of course using L.
    > >> ^^^^^^^ ^^^^^^^^^

    > >
    > >An advice how to solve the OP's problem.

    >
    > It's a lot more than that. It's *also* an implication that the OP's
    > way was incorrect. And a strong clue that you believed the OP's code
    > to be incorrect.
    >
    > A properly phrased advice would have been something along the lines:
    > "you can shut up the bogus warning by using the L suffix".


    On the second thought, I think you're right. Sorry about (potentially)
    misleading the OP.
    Peter Pichler, Feb 26, 2004
    #11
  12. Ross

    Ross Guest

    Thanks for the replies and discussion.

    The explanation makes sense regarding the bit length of INT versus
    Long - and it did indeed seem like a bug in the compiler.

    The compiler (for those interested) is ImageCraft - within the
    Cypress tools.

    (Not so much to diss either of those co's, but just in case someone
    else is searching to explain the same problem later)

    Thanks again,

    Ross.

    The 'L' suffix appears to be the best work around.

    On Tue, 24 Feb 2004 23:16:19 GMT, wrote:

    >Ross <> wrote:
    >>
    >> The specific instance of the "-6" in this phrase generates a warning:
    >>
    >> const signed long tzerocal_A[] ={80000, 15000, -60000 }; //bad

    >[...]
    >> [warning] unsigned operand of unary -
    >>
    >> Can anyone explain why this is happening.

    >
    >Because your compiler is broken. It appears to be treating unsuffixed
    >decimal constants between INT_MAX and UINT_MAX as having type unsigned
    >int, but the C Standard requires them to have type long int (unlike
    >octal and hex constants, decimal constants are *never* interpreted as
    >unsigned without an explicit u or U suffix).
    >
    >-Larry Jones
    >
    >The surgeon general should issue a warning about playing with girls. -- Calvin
    Ross, Feb 27, 2004
    #12
    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. Chao
    Replies:
    6
    Views:
    1,264
    Mike Treseler
    Jul 5, 2004
  2. =?Utf-8?B?S3Vt?=
    Replies:
    1
    Views:
    787
    Peter Blum
    Jun 8, 2005
  3. Brandon McCombs

    how to solve this warning in Eclipse?

    Brandon McCombs, Mar 12, 2006, in forum: Java
    Replies:
    16
    Views:
    44,161
    Chris Smith
    Mar 26, 2006
  4. Stedwick
    Replies:
    3
    Views:
    100
    Stedwick
    Feb 14, 2008
  5. Raistlin Majere

    Can you solve a problem like this?

    Raistlin Majere, May 3, 2006, in forum: Perl Misc
    Replies:
    9
    Views:
    143
    Anno Siegel
    May 4, 2006
Loading...

Share This Page