Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Why, warning: comparison between signed and unsigned integer expressions?

Reply
Thread Tools

Why, warning: comparison between signed and unsigned integer expressions?

 
 
Lox
Guest
Posts: n/a
 
      05-29-2012
Hello all experts. If I compile the following code (small example) I
get "warning: comparison between signed and unsigned integer
expressions".

void test(void)
{
uint8_t a;
uint32_t i;

a = 10;

for(i = 0; i < (a + 1); i++)
{

}
}

But the following code doesn't give that warning:


void test(void)
{
uint8_t a;
uint32_t i;

a = 10;

for(i = 0; i < (uint32_t)(a + 1); i++)
{

}
}

What is going on here? Why does the compiler think (a + 1) is signed?
 
Reply With Quote
 
 
 
 
Ike Naar
Guest
Posts: n/a
 
      05-29-2012
On 2012-05-29, bartek szurgot <> wrote:
> hi,
>
> On 05/29/2012 08:15 AM, Lox wrote:
>> Hello all experts. If I compile the following code (small example) I
>> get "warning: comparison between signed and unsigned integer
>> expressions".
>>
>> void test(void)
>> {
>> uint8_t a;
>> uint32_t i;
>>
>> a = 10;
>>
>> for(i = 0; i < (a + 1); i++)
>> {
>>
>> }
>> }

>
> what compiler are you using? i'm unable to reproduce this warning on
> gcc-4.[567]


Use the -Wextra option.
 
Reply With Quote
 
 
 
 
Ike Naar
Guest
Posts: n/a
 
      05-29-2012
On 2012-05-29, Lox <> wrote:
> Hello all experts. If I compile the following code (small example) I
> get "warning: comparison between signed and unsigned integer
> expressions".
>
> void test(void)
> {
> uint8_t a;
> uint32_t i;
>
> a = 10;
>
> for(i = 0; i < (a + 1); i++)
> {
>
> }
> }


Integer promotions.
In i < (a + 1), a is promoted to an int because, apparently on your
implementation, int can represent all values of type uint8_t.

The promoted a (int) and 1 (int) are added, yielding int (a + 1) .
The operands of the comparison are uint32_t and int, hence the warning.

> But the following code doesn't give that warning:
>
>
> void test(void)
> {
> uint8_t a;
> uint32_t i;
>
> a = 10;
>
> for(i = 0; i < (uint32_t)(a + 1); i++)
> {
>
> }
> }


Here the int expression (a + 1) is explicitly converted
to uint32_t, so the comparison is between two uint32_t's.
 
Reply With Quote
 
Lox
Guest
Posts: n/a
 
      05-29-2012
I get the same warning when i use:

void test(void)
{
uint8_t a;
uint32_t i;
a = 10;
for(i = 0; i < (a + UINT8_C(1)); i++)
{
}
}

and also on:

void test(void)
{
uint8_t a;
uint32_t i;
a = 10;
for(i = 0; i < ((uint8_t)a + (uint8_t)1); i++)
{
}
}

I'm using Ride7 IDE from Raisonance. It uses some form of GCC for ARM
(arm-none-eabi-gcc.exe).

But I think it is solved now when I understand that char and short
gets promoted to int. Thank you all.

On May 29, 9:21*am, bartek szurgot <b...@no.spam> wrote:
> hi,
>
> On 05/29/2012 08:15 AM, Lox wrote:


> what compiler are you using? i'm unable to reproduce this warning on
> gcc-4.[567] and clang-3.0, but id say that a+1 is uint8_t+int, that
> gives int, thus signed. try a+1u instead.



 
Reply With Quote
 
BartC
Guest
Posts: n/a
 
      05-29-2012


"Ike Naar" <> wrote in message
news:. ..
> On 2012-05-29, Lox <> wrote:
>> Hello all experts. If I compile the following code (small example) I
>> get "warning: comparison between signed and unsigned integer
>> expressions".
>>
>> void test(void)
>> {
>> uint8_t a;
>> uint32_t i;
>>
>> a = 10;
>>
>> for(i = 0; i < (a + 1); i++)
>> {
>>
>> }
>> }

>
> Integer promotions.
> In i < (a + 1), a is promoted to an int because, apparently on your
> implementation, int can represent all values of type uint8_t.


So all the discussion in the recent thread ("condition true or false? ...")
about mixed arithmetic being unsigned, isn't always true?

(Yes I've now read 6.3.1.8. But why would C care more about preserving
possible negative values of a wider int, than the negative values of a
narrower int? The mixed arithmetic rule could have been more consistent.)

--
Bartc

 
Reply With Quote
 
Lox
Guest
Posts: n/a
 
      05-29-2012
I also tested the integer promotion in the following examples.

uint32_t x;
uint8_t y;

x = 255;
y = x + UINT8_C(1);

y is 256 and not 255 as one would think.

but in:

uint32_t x;
uint8_t y;

x = 255;
y = (u8_t)(x + UINT8_C(1));

y is 255


 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      05-29-2012
On 05/29/2012 03:56 AM, Ike Naar wrote:
....
> In i < (a + 1), a is promoted to an int because, apparently on your
> implementation, int can represent all values of type uint8_t.


That's not specific to his implementation. uint8_t is an exact-sized
type, so UINT8_MAX has to be 255. An implementation where CHAR_BITS>8
cannot implement uint8_t, and therefore must NOT provide it. INT_MAX is
not allowed to be less than 32767, so uint8_t always promotes to int.
--
James Kuyper
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      05-29-2012
On 05/29/2012 05:02 AM, BartC wrote:
> "Ike Naar" <> wrote in message
> news:. ..
>> On 2012-05-29, Lox <> wrote:

....
>>> void test(void)
>>> {
>>> uint8_t a;
>>> uint32_t i;
>>>
>>> a = 10;
>>>
>>> for(i = 0; i < (a + 1); i++)
>>> {
>>>
>>> }
>>> }

>>
>> Integer promotions.
>> In i < (a + 1), a is promoted to an int because, apparently on your
>> implementation, int can represent all values of type uint8_t.

>
> So all the discussion in the recent thread ("condition true or false? ...")
> about mixed arithmetic being unsigned, isn't always true?


A lot of things were said in that discussion by people with varying
levels of understanding of the language. What actually happens depends
upon the usual arithmetic conversions, which start with the integer
promotions. The assertion some participants made that "mixed arithmetic
is unsigned" was, at best, a simplification that becomes false under two
circumstances:

1. If all possible values of the unsigned type can be represented as an
'int', the unsigned value is promoted to an 'int'. The same rule applies
to the signed type. The expression is evaluated using whichever promoted
type has the higher integer conversion rank.

2. If the expression still has mixed signedness after the integer
promotions, the following rule applies to the promoted types of the
operands. If the unsigned type and has an integer conversion rank less
than that of the signed type, and all values of the unsigned type can be
represented in the signed type, then the expression is evaluated using
the signed type.

> (Yes I've now read 6.3.1.8. But why would C care more about preserving
> possible negative values of a wider int, than the negative values of a
> narrower int? The mixed arithmetic rule could have been more consistent.)


One key concept in C is that 'int' and 'unsigned int' were chosen by the
implementation to be the natural type for ordinary integer arithmetic.
Therefore, C requires promotion to one of those two types, if the result
is value preserving, before anything other aspect of the usual
arithmetic conversions are applied. It is consistent application of that
rule that produces the result that you consider inconsistent.
--
James Kuyper
 
Reply With Quote
 
Ike Naar
Guest
Posts: n/a
 
      05-29-2012
On 2012-05-29, Lox <> wrote:
> I also tested the integer promotion in the following examples.
>
> uint32_t x;
> uint8_t y;
>
> x = 255;
> y = x + UINT8_C(1);
>
> y is 256 and not 255 as one would think.


Two questions:
- why would one think that y would be 255 ?
- uint8_t can hold the values [0,255], so how could y ever be 256 ?

> but in:
>
> uint32_t x;
> uint8_t y;
>
> x = 255;
> y = (u8_t)(x + UINT8_C(1));
>
> y is 255


Very unlikely. How did you come to that conclusion?
 
Reply With Quote
 
Lox
Guest
Posts: n/a
 
      05-31-2012
Sorry, two typos (wrote to fast).

uint32_t x;
uint8_t y;

x = 255;
y = x + UINT8_C(1);

y is 256 and not 0 as one would think (if assuming 8 bit
calculations).

but in:

uint32_t x;
uint8_t y;

x = 255;
y = (u8_t)(x + UINT8_C(1));

y is 0



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
comparison between signed and unsigned int compcreator@gmail.com C Programming 6 09-21-2007 07:37 PM
comparison between signed and unsigned integer expressions Gary Wessle C++ 4 07-29-2006 05:56 AM
comparison between signed int and unsigned int Alex C Programming 3 04-26-2006 05:20 AM
conversion of signed integer to unsigned integer junky_fellow@yahoo.co.in C Programming 14 06-18-2005 02:29 PM
comparison between signed and unsigned John Buckley C Programming 2 10-24-2003 11:53 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57