Re: [IDEA+RFC] Possible solution for min()/max() war

Herbert Rosmanith (herp@wildsau.idv-edu.uni-linz.ac.at)
Thu, 30 Aug 2001 11:56:07 +0200 (MET DST)


> Please guys. The issue of sign in comparisons are a LOT more complicated
> than most of you seem to think.

as a friend of mine put it on IRC:
"Your little brains are not able to grasp the complicated issue of
sign in comparisons."

If the problem is compiler-related, shouldn't it be forwared to the
gcc-group?

e.g.:

: void foo() {
: unsigned int i;
: signed int j;
:
: i=j;
: }

does not generated a warning even with "-Wall". I think it should print
out something like "warning: sign will be lost in signed to unsigned
assignment".

The rules for signed/unsigned comparison should be:
o the sign is always "sticky" (i.e. signed/unsigned -> signed)
o data size is expanded to the size of the larger var.
o (1) if the larger var is unsigned, data size is expanded
even further.
(2) if that's not possible, use carry flag.

However, I noticed that this "value-preserving arithmetic conversion"
is not always performed.

code follows:

: #include <stdio.h>
:
: int main() {
:
: unsigned char ca;
: signed char cb;
:
: unsigned short sa;
: signed short sb;
:
: unsigned int ia;
: signed int ib;
:
: ca=0xff;
: cb=0xff;
: printf("ca=%u cb=%d\n",ca,cb);
: if (ca<cb) printf("ca<cb\n");
: else if (ca>cb) printf("ca>cb\n");
: else printf("ca==cb\n");
:
: sa=0xffff;
: sb=0xffff;
: printf("sa=%u sb=%hd\n",sa,sb);
: if (sa<sb) printf("sa<sb\n");
: else if (sa>sb) printf("sa>sb\n");
: else printf("sa==sb\n");
:
: ia=0xffffffff;
: ib=0xffffffff;
: printf("ia=%u ib=%d\n",ia,ib);
: if (ia<ib) printf("ia<ib\n");
: else if (ia>ib) printf("ia>ib\n");
: else printf("ia==ib\n");
:
: return 0;
: }

will result to:

: bash-2.03# cc -Wsign-compare -o cm cm.c
: cm.c: In function `main':
: cm.c:32: warning: comparison between signed and unsigned
: cm.c:33: warning: comparison between signed and unsigned
: bash-2.03# ./cm
: ca=255 cb=-1
: ca>cb
: sa=65535 sb=-1
: sa>sb
: ia=4294967295 ib=-1
: ia==ib

so, in the "int" case, the result of the comparison is wrong. (shouldnt
it be expanded to long long, or at least use the carry-flag?)
If the min/max macros explicitly cast a signed data-type to an
unsigned one, the meaning of the sign-bit will be lost in any
way, not only in the int-case.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/