Comparing singed to unsinged warning

N

Nevil Lesdog

What do you think is the best way to handle a compiler warning about
comparing an unsinged value to a singed value? Cast to silence it?
Disable that warning altogether? Or just live with it?

On one hand, the warning *could* be useful. Most of the time I get it in
cases where I know the comparison is safe, but it's not hard to imagine
that this won't always be the case. This makes disabling it undesirable.
Casting is a workable solution, but I worry that changes in the code
later could introduce errors that go undetected due to the cast. And I
think we all hate not having a "clean" compile (if only because having a
bunch of warnings that you expected makes it more difficult to spot the
ones you didn't expect).

What is your opinion?
 
A

Al Balmer

What do you think is the best way to handle a compiler warning about
comparing an unsinged value to a singed value? Cast to silence it?
Disable that warning altogether? Or just live with it?

Look at the code and make darned sure you understand why the warning
occurred, and why it was necessary to compare things of two different
type. Then, if you still think it was the right thing to do, use a
cast, which will at least indicate that you did it on purpose.
On one hand, the warning *could* be useful. Most of the time I get it in
cases where I know the comparison is safe, but it's not hard to imagine
that this won't always be the case. This makes disabling it undesirable.
Casting is a workable solution, but I worry that changes in the code
later could introduce errors that go undetected due to the cast. And I
think we all hate not having a "clean" compile (if only because having a
bunch of warnings that you expected makes it more difficult to spot the
ones you didn't expect).

What is your opinion?

My opinion is that there's a very good chance that the code could be
better written.
 
C

CBFalconer

Nevil said:
What do you think is the best way to handle a compiler warning about
comparing an unsinged value to a singed value? Cast to silence it?
Disable that warning altogether? Or just live with it?

None of those. Consider whether values should be 'singed' or not.
On one hand, the warning *could* be useful. Most of the time I get it in
cases where I know the comparison is safe, but it's not hard to imagine
that this won't always be the case. This makes disabling it undesirable.
Casting is a workable solution, but I worry that changes in the code
later could introduce errors that go undetected due to the cast. And I
think we all hate not having a "clean" compile (if only because having a
bunch of warnings that you expected makes it more difficult to spot the
ones you didn't expect).

If a negative value ever appears in either compareee, the
comparison is NOT safe.
 
P

pete

Nevil said:
What do you think is the best way to handle a compiler warning about
comparing an unsinged value to a singed value?
Cast to silence it?
No.

Disable that warning altogether?
No!

Or just live with it?
No!!

On one hand, the warning *could* be useful.

It most likely *is* useful.

Rewrite the code so that there is no singed/unsinged mismatch,
otherwise you might get signed by the heat.
Most of the time I get it in
cases where I know the comparison is safe,
but it's not hard to imagine
that this won't always be the case.
This makes disabling it undesirable.
Casting is a workable solution, but I worry that changes in the code
later could introduce errors that go undetected due to the cast. And I
think we all hate not having a "clean" compile
(if only because having a bunch of warnings that
you expected makes it more difficult to spot the
ones you didn't expect).

What is your opinion?

Change the sign type of one of your operands.
 
A

Ark Khasin

pete said:
It most likely *is* useful.

Rewrite the code so that there is no singed/unsinged mismatch,
otherwise you might get signed by the heat.


Change the sign type of one of your operands.
In Steven Colbert's words, Here is your today's word: Wrap it!

There are legitimate reasons why a mixed-signedness operations may be
necessary.
Imagine e.g. a function whose job is to scale and offset the argument,
limit the result from above and from below and output it to a DAC register.
An appropriate model for a DAC and perhaps for the lower and upper
limits is unsigned, whereas for scaling and offsetting a natural model
is signed.
At some point, a leap from one signedness to the other is necessary.

If the function is very small, a typecast (and a good comment) will do.
Otherwise, wrap it in a proof that you know what you are doing, like

#define INT2UINT(x) (assert((x)>=0),(unsigned)(x))

assuming you don't pass it an expression with side effects. Or make an
inline function to that effect.

-- Ark
 
A

Alexei A. Frounze

What do you think is the best way to handle a compiler warning about
comparing an unsinged value to a singed value? Cast to silence it?
Disable that warning altogether? Or just live with it?

On one hand, the warning *could* be useful. Most of the time I get it in
cases where I know the comparison is safe, but it's not hard to imagine
that this won't always be the case. This makes disabling it undesirable.
Casting is a workable solution, but I worry that changes in the code
later could introduce errors that go undetected due to the cast. And I
think we all hate not having a "clean" compile (if only because having a
bunch of warnings that you expected makes it more difficult to spot the
ones you didn't expect).

What is your opinion?

You could compare them using a dedicated function like in this
program:

#include <stdio.h>
#include <limits.h>

int CmpSU (int s, unsigned int u)
// compares signed int s and unsigned int u;
// returns: -1 if s < u
// 0 if s == u
// 1 if s > u
{
if (s >= 0)
{
if ((unsigned int)s < u) return -1;
else if ((unsigned int)s > u) return 1;
return 0;
}
return -1;
}

struct
{
int s;
unsigned u;
} aTestValues[] =
{
{INT_MIN, 0},
{INT_MIN, 1},
{INT_MIN, INT_MAX},
{INT_MIN, UINT_MAX},
{-1, 0},
{-1, 1},
{-1, INT_MAX},
{-1, UINT_MAX},
{0, 0},
{0, 1},
{0, INT_MAX},
{0, UINT_MAX},
{1, 0},
{1, 1},
{1, INT_MAX},
{1, UINT_MAX},
{INT_MAX, 0},
{INT_MAX, 1},
{INT_MAX, INT_MAX},
{INT_MAX, UINT_MAX},
};

int main (void)
{
int i;
for (i = 0;
i < sizeof(aTestValues)/sizeof(aTestValues[0]);
i++)
{
int s = aTestValues.s;
unsigned int u = aTestValues.u;
printf ("%d %c %u\n",
s,
"<=>"[1+CmpSU(s,u)],
u);
}
return 0;
}


Alex
 
P

pete

Ark said:
In Steven Colbert's words, Here is your today's word: Wrap it!

There are legitimate reasons why a mixed-signedness operations may be
necessary.
Imagine e.g. a function whose job is to scale and offset the argument,
limit the result from above and from below
and output it to a DAC register.
An appropriate model for a DAC and perhaps for the lower and upper
limits is unsigned, whereas for scaling and offsetting a natural model
is signed.
At some point, a leap from one signedness to the other is necessary.

If the function is very small,
a typecast (and a good comment) will do.
Otherwise, wrap it in a proof that you know what you are doing, like

#define INT2UINT(x) (assert((x)>=0),(unsigned)(x))

assuming you don't pass it an expression with side effects. Or make an
inline function to that effect.

That's all over my head.
In my limited experience, I have never had to write code
that used a relational operator
with signed and unsigned operand types at the same time.

The one time that I encountered it in a project that I was working
on, the contract called for a clean compile and I had to fix it.
Aside from generating a warning, the implicit conversion
also rendered the controling expression of an "if" statement
as always flase. I don't remember any other details
except that I changed one of the types, so that
the error condition that the code was supposed to check for,
actually got checked for.
 
A

Ark Khasin

pete said:
That's all over my head.
In my limited experience, I have never had to write code
that used a relational operator
with signed and unsigned operand types at the same time.

The one time that I encountered it in a project that I was working
on, the contract called for a clean compile and I had to fix it.
Aside from generating a warning, the implicit conversion
also rendered the controling expression of an "if" statement
as always flase. I don't remember any other details
except that I changed one of the types, so that
the error condition that the code was supposed to check for,
actually got checked for.
I don't think there is any disagreement at all.
If you can refactor the code to avoid type mismatch, good. (And indeed
in most cases I've seen a type mismatch, it /is/ the result of sloppy
coding.)
There are cases though where signedness change is necessary.

-- Ark
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top