Re: moused(8): char signed-ness problem with gcc 3.1
On Thu, May 16, 2002 at 06:47:39AM -0400, Thomas David Rivers wrote: > > Terry Lambert <[EMAIL PROTECTED]> wrote: > > RS/6000's didn't used to use PPC processors at all; so it's > > probably intentional software compatability. > > I'm confused then - the one we have here seems to. There > was a version of something very RS/6000-like that didn't, > but I thought RS/6000s did... > RS/6000s used to use Power before there was PowerPC. I'm doubting there is much difference between the two from a software point of view. To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Re: moused(8): char signed-ness problem with gcc 3.1
> Sounds like you should forward this to [EMAIL PROTECTED] :-) > CC audit@ (and current@) so we can all see what the GNU people say. > Don't forget to show the output of `cc -v'. knu has already created a gnats pr with gcc and posted the url. -- David W. Chapman Jr. [EMAIL PROTECTED] Raintree Network Services, Inc. [EMAIL PROTECTED] FreeBSD Committer To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Re: moused(8): char signed-ness problem with gcc 3.1
On Thu, May 16, 2002 at 12:06:49PM -0700, Bill Fenner wrote: > >Specifically what is the problem? Given the program below, take the > >ISO-C spec and explain the problem. Or even w/o the spec -- I haven't > >been reading this thread. > > > > int > > > main() > > > { > > >unsigned char i = 127; > > >char j; > > > > > >printf("%d\n", ((char)(i << 1))); > > This prints -2, which is correct -- (signed char)254 is -2. > > > >j = ((char)(i << 1)) / 2; > > >printf("%d\n", j); > > This prints 127, which is incorrect. -2 / 2 is -1. > > > >j = ((char)(i << 1)); > > >printf("%d\n", j / 2); > > This breaks down the previous expression into two halves, and > results in the correct answer of -1. However, there should > be no difference between > ((char)(i << 1)) / 2 > and > char j = ((char)(i << 1); j / 2 Sounds like you should forward this to [EMAIL PROTECTED] :-) CC audit@ (and current@) so we can all see what the GNU people say. Don't forget to show the output of `cc -v'. Or run `gccbug' from a recient gcc31 port install. If you do this instead, please send me the PR #. To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Re: moused(8): char signed-ness problem with gcc 3.1
>Specifically what is the problem? Given the program below, take the >ISO-C spec and explain the problem. Or even w/o the spec -- I haven't >been reading this thread. > > int > > main() > > { > >unsigned char i = 127; > >char j; > > > >printf("%d\n", ((char)(i << 1))); This prints -2, which is correct -- (signed char)254 is -2. > >j = ((char)(i << 1)) / 2; > >printf("%d\n", j); This prints 127, which is incorrect. -2 / 2 is -1. > >j = ((char)(i << 1)); > >printf("%d\n", j / 2); This breaks down the previous expression into two halves, and results in the correct answer of -1. However, there should be no difference between ((char)(i << 1)) / 2 and char j = ((char)(i << 1); j / 2 Bill To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Re: moused(8): char signed-ness problem with gcc 3.1
On Thu, May 16, 2002 at 08:31:19PM +0900, Akinori MUSHA wrote: > > > So - yes - it seems gcc 3.1 does have a problem... > > Indeed - easily determined by breaking down the expression. > > So, who's gonna report it to gcc-bugs? knu?... Specifically what is the problem? Given the program below, take the ISO-C spec and explain the problem. Or even w/o the spec -- I haven't been reading this thread. > > int > > main() > > { > >unsigned char i = 127; > >char j; > > > >printf("%d\n", ((char)(i << 1))); > >j = ((char)(i << 1)) / 2; > >printf("%d\n", j); > >j = ((char)(i << 1)); > >printf("%d\n", j / 2); > >return 0; > > } > > Somehow, specifying -fsigned-char, which I thought was the default, > fixed the problem. So, the cause may be in our configuration of gcc? To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Re: moused(8): char signed-ness problem with gcc 3.1
I've submitted a bug report to GCC GNATS: http://gcc.gnu.org/cgi-bin/gnatsweb.pl?database=gcc&pr=6677&cmd=view+audit-trail Let's see how they handle this. -- / /__ __Akinori.org / MUSHA.org / ) ) ) ) / FreeBSD.org / Ruby-lang.org Akinori MUSHA aka / (_ / ( (__( @ iDaemons.org / and.or.jp "Somewhere out of a memory.. of lighted streets on quiet nights.." To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Re: moused(8): char signed-ness problem with gcc 3.1
At Thu, 16 May 2002 21:58:56 +1000 (EST), Bruce Evans wrote: > > Somehow, specifying -fsigned-char, which I thought was the default, > > fixed the problem. So, the cause may be in our configuration of gcc? > > -fsigned-char doesn't fix it for me. Neither does repacling "char" by > "signed char". Oops, I was testing on a different box. Sorry. > moused is broken too. It assumes that plain chars are signed. How about this? Index: moused.c === RCS file: /home/ncvs/src/usr.sbin/moused/moused.c,v retrieving revision 1.55 diff -u -r1.55 moused.c --- moused.c28 Apr 2002 11:59:30 - 1.55 +++ moused.c16 May 2002 14:15:42 - @@ -1718,8 +1718,8 @@ return 0; } - act->dx = (char)(((pBuf[0] & 0x03) << 6) | (pBuf[1] & 0x3F)); - act->dy = (char)(((pBuf[0] & 0x0C) << 4) | (pBuf[2] & 0x3F)); + act->dx = (signed char)(((pBuf[0] & 0x03) << 6) | (pBuf[1] & 0x3F)); + act->dy = (signed char)(((pBuf[0] & 0x0C) << 4) | (pBuf[2] & 0x3F)); break; case MOUSE_PROTO_GLIDEPOINT: /* GlidePoint */ @@ -1728,8 +1728,8 @@ MouseMan+ */ act->button = (act->obutton & (MOUSE_BUTTON2DOWN | MOUSE_BUTTON4DOWN)) | butmapmss[(pBuf[0] & MOUSE_MSS_BUTTONS) >> 4]; - act->dx = (char)(((pBuf[0] & 0x03) << 6) | (pBuf[1] & 0x3F)); - act->dy = (char)(((pBuf[0] & 0x0C) << 4) | (pBuf[2] & 0x3F)); + act->dx = (signed char)(((pBuf[0] & 0x03) << 6) | (pBuf[1] & 0x3F)); + act->dy = (signed char)(((pBuf[0] & 0x0C) << 4) | (pBuf[2] & 0x3F)); break; case MOUSE_PROTO_MSC: /* MouseSystems Corp */ @@ -1737,15 +1737,15 @@ case MOUSE_PROTO_MARIQUA: /* Mariqua */ #endif act->button = butmapmsc[(~pBuf[0]) & MOUSE_MSC_BUTTONS]; - act->dx =(char)(pBuf[1]) + (char)(pBuf[3]); - act->dy = - ((char)(pBuf[2]) + (char)(pBuf[4])); + act->dx =(signed char)(pBuf[1]) + (signed char)(pBuf[3]); + act->dy = - ((signed char)(pBuf[2]) + (signed char)(pBuf[4])); break; case MOUSE_PROTO_JOGDIAL: /* JogDial */ if (rBuf == 0x6c) - act->dz=-1; + act->dz = -1; if (rBuf == 0x72) - act->dz=1; + act->dz = 1; if (rBuf == 0x64) act->button = MOUSE_BUTTON1DOWN; if (rBuf == 0x75) @@ -1792,8 +1792,8 @@ case MOUSE_PROTO_BUS: /* Bus */ case MOUSE_PROTO_INPORT: /* InPort */ act->button = butmapmsc[(~pBuf[0]) & MOUSE_MSC_BUTTONS]; - act->dx = (char)pBuf[1]; - act->dy = - (char)pBuf[2]; + act->dx = (signed char)pBuf[1]; + act->dy = - (signed char)pBuf[2]; break; case MOUSE_PROTO_PS2: /* PS/2 */ @@ -1822,7 +1822,7 @@ case MOUSE_MODEL_INTELLI: case MOUSE_MODEL_NET: /* wheel data is in the fourth byte */ - act->dz = (char)pBuf[3]; + act->dz = (signed char)pBuf[3]; if ((act->dz >= 7) || (act->dz <= -7)) act->dz = 0; /* some compatible mice may have additional buttons */ @@ -1969,10 +1969,10 @@ case MOUSE_PROTO_SYSMOUSE: /* sysmouse */ act->button = butmapmsc[(~pBuf[0]) & MOUSE_SYS_STDBUTTONS]; - act->dx =(char)(pBuf[1]) + (char)(pBuf[3]); - act->dy = - ((char)(pBuf[2]) + (char)(pBuf[4])); + act->dx =(signed char)(pBuf[1]) + (signed char)(pBuf[3]); + act->dy = - ((signed char)(pBuf[2]) + (signed char)(pBuf[4])); if (rodent.level == 1) { - act->dz = ((char)(pBuf[5] << 1) + (char)(pBuf[6] << 1))/2; + act->dz = ((signed char)(pBuf[5] << 1) + (signed char)(pBuf[6] << 1)) >> 1; act->button |= ((~pBuf[7] & MOUSE_SYS_EXTBUTTONS) << 3); } break; -- / /__ __Akinori.org / MUSHA.org / ) ) ) ) / FreeBSD.org / Ruby-lang.org Akinori MUSHA aka / (_ / ( (__( @ iDaemons.org / and.or.jp "Somewhere out of a memory.. of lighted streets on quiet nights.." To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Re: moused(8): char signed-ness problem with gcc 3.1
On Thu, 16 May 2002, Akinori MUSHA wrote: > [CC: obrien, who has been working on bringing in gcc 3.1] > > At Wed, 15 May 2002 20:46:06 -0700, > Bill Fenner wrote: > > So, who's gonna report it to gcc-bugs? knu?... > > > > int > > main() > > { > >unsigned char i = 127; > >char j; > > > >printf("%d\n", ((char)(i << 1))); > >j = ((char)(i << 1)) / 2; > >printf("%d\n", j); > >j = ((char)(i << 1)); > >printf("%d\n", j / 2); > >return 0; > > } > > Somehow, specifying -fsigned-char, which I thought was the default, > fixed the problem. So, the cause may be in our configuration of gcc? -fsigned-char doesn't fix it for me. Neither does repacling "char" by "signed char". moused is broken too. It assumes that plain chars are signed. Bruce To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Re: moused(8): char signed-ness problem with gcc 3.1
[CC: obrien, who has been working on bringing in gcc 3.1] At Wed, 15 May 2002 20:46:06 -0700, Bill Fenner wrote: > > So - yes - it seems gcc 3.1 does have a problem... > > Indeed - easily determined by breaking down the expression. > > So, who's gonna report it to gcc-bugs? knu?... > > int > main() > { >unsigned char i = 127; >char j; > >printf("%d\n", ((char)(i << 1))); >j = ((char)(i << 1)) / 2; >printf("%d\n", j); >j = ((char)(i << 1)); >printf("%d\n", j / 2); >return 0; > } Somehow, specifying -fsigned-char, which I thought was the default, fixed the problem. So, the cause may be in our configuration of gcc? I'll send-pr if it isn't. -- / /__ __Akinori.org / MUSHA.org / ) ) ) ) / FreeBSD.org / Ruby-lang.org Akinori MUSHA aka / (_ / ( (__( @ iDaemons.org / and.or.jp "Somewhere out of a memory.. of lighted streets on quiet nights.." To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Re: moused(8): char signed-ness problem with gcc 3.1
Terry Lambert <[EMAIL PROTECTED]> wrote: > Thomas David Rivers wrote: > > Well - it's not counter-intuitive on many machines... For example, > > on the IBM mainframe - there is an instruction to load a character > > into a register - but not one that loads *and* sign-extends. So, > > you can get much better code if characters are unsigned by default. > > Sounds like time to get out the wire wrap tools... and fix the > hardware, not the software. Ha! That may not be a bad idea :-) > > > So in our C/C++ compilers for the mainframe, the default is > > unsigned as well. > > > > I wonder if the AIX people were looking for mainframe > > compatibility in this decision, or was it motivated > > by the PowerPC instruction set? Does anyone know what > > the Mac default is (since they are PowerPC based as well?) > > RS/6000's didn't used to use PPC processors at all; so it's > probably intentional software compatability. I'm confused then - the one we have here seems to. There was a version of something very RS/6000-like that didn't, but I thought RS/6000s did... - Dave Rivers - -- [EMAIL PROTECTED]Work: (919) 676-0847 Get your mainframe programming tools at http://www.dignus.com To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Re: moused(8): char signed-ness problem with gcc 3.1
Thomas David Rivers wrote: > Well - it's not counter-intuitive on many machines... For example, > on the IBM mainframe - there is an instruction to load a character > into a register - but not one that loads *and* sign-extends. So, > you can get much better code if characters are unsigned by default. Sounds like time to get out the wire wrap tools... and fix the hardware, not the software. > So in our C/C++ compilers for the mainframe, the default is > unsigned as well. > > I wonder if the AIX people were looking for mainframe > compatibility in this decision, or was it motivated > by the PowerPC instruction set? Does anyone know what > the Mac default is (since they are PowerPC based as well?) RS/6000's didn't used to use PPC processors at all; so it's probably intentional software compatability. -- Terry To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Re: moused(8): char signed-ness problem with gcc 3.1
> So - yes - it seems gcc 3.1 does have a problem... Indeed - easily determined by breaking down the expression. So, who's gonna report it to gcc-bugs? knu?... int main() { unsigned char i = 127; char j; printf("%d\n", ((char)(i << 1))); j = ((char)(i << 1)) / 2; printf("%d\n", j); j = ((char)(i << 1)); printf("%d\n", j / 2); return 0; } Bill To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Re: moused(8): char signed-ness problem with gcc 3.1
Terry Lambert <[EMAIL PROTECTED]> wrote: > > Bill Fenner wrote: > > gcc 3.1 simply defaults to unsigned chars. 127 << 1 = 254; 254 / 2 = 127. > > > > My machine is too slow to test this expeditiously, but I'm trying > > adding "#define DEFAULT_SIGNED_CHAR 1" into freebsd-native.h . > > I will bet today's lunch money that you have found it for sure. > > I guess we will have to go around adding "signed" everywhere, if > it's no longer the default. > > Unsigned is a stupid, counter-intuitive default, and has been, > ever since I first used AIX. > > My bet is a conspiracy by AIX folks so that Open Source software > will work on AIX without them having to fix their stupid defaults. > > 8-) 8-). Well - it's not counter-intuitive on many machines... For example, on the IBM mainframe - there is an instruction to load a character into a register - but not one that loads *and* sign-extends. So, you can get much better code if characters are unsigned by default. So in our C/C++ compilers for the mainframe, the default is unsigned as well. I wonder if the AIX people were looking for mainframe compatibility in this decision, or was it motivated by the PowerPC instruction set? Does anyone know what the Mac default is (since they are PowerPC based as well?) - Dave Rivers - -- [EMAIL PROTECTED]Work: (919) 676-0847 Get your mainframe programming tools at http://www.dignus.com To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Re: moused(8): char signed-ness problem with gcc 3.1
> > I observed gcc 2.95.4 and gcc 3.1 interpret (or maybe optimize) the > following code differently (CFLAGS=-O): > > int main(void) > { > unsigned char i = 127; > printf("%d\n", ((char)(i << 1)) / 2); > return 0; > } > > gcc 2.95.4 says it's -1, whereas gcc 3.1 says it's 127. On FreeBSD > char should be signed, so I suspect it's a (optimization) bug of gcc > 3.1 which should be fixed. Or we'll have to do a mass audit of the > whole src tree to check and fix the similar expressions. Let's examine the what the "right" answer should be: First - in the expression (i << 1) - the unsigned char `i' will be promoted to a signed int through the correct integral promotion rules, then left-shifted 1 bit. The result of that is an int. So - this becomes: ((char)(254)) / 2 ; The expression: (char)(254) is then also promoted to int when it participates in the division operation. So, the value 254 is converted into a (signed) char, and then converted to an int. Converting 254 to a signed character should result in an integer value of -2. Then, -2 / 2 becomes -1. If characters were unsigned by default, you do get the value 127... So - yes - it seems gcc 3.1 does have a problem... - Dave Rivers - -- [EMAIL PROTECTED]Work: (919) 676-0847 Get your mainframe programming tools at http://www.dignus.com To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Re: moused(8): char signed-ness problem with gcc 3.1
Bill Fenner wrote: > Duh. Sometimes I wish I had the patience to wait for my tests to complete > before sharing my guesses. I jumped to a wildly incorrect conclusion; gcc > 3.1 still defaults to signed chars. Sorry for the bizarre misdirection. There goes my lunch money. 8-(. Man, your explanation was preferrable to a real bug. 8-(. -- Terry To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Re: moused(8): char signed-ness problem with gcc 3.1
Duh. Sometimes I wish I had the patience to wait for my tests to complete before sharing my guesses. I jumped to a wildly incorrect conclusion; gcc 3.1 still defaults to signed chars. Sorry for the bizarre misdirection. Bill To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Re: moused(8): char signed-ness problem with gcc 3.1
Bill Fenner wrote: > gcc 3.1 simply defaults to unsigned chars. 127 << 1 = 254; 254 / 2 = 127. > > My machine is too slow to test this expeditiously, but I'm trying > adding "#define DEFAULT_SIGNED_CHAR 1" into freebsd-native.h . I will bet today's lunch money that you have found it for sure. I guess we will have to go around adding "signed" everywhere, if it's no longer the default. Unsigned is a stupid, counter-intuitive default, and has been, ever since I first used AIX. My bet is a conspiracy by AIX folks so that Open Source software will work on AIX without them having to fix their stupid defaults. 8-) 8-). If this isn't the default, then "signed" is too much like "const" and "volatile" and other "you can't ignore them or I will generate bad code" keywords. -- Terry To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Re: moused(8): char signed-ness problem with gcc 3.1
On Thu, May 16, 2002 at 02:42:34AM +0900, Akinori MUSHA wrote: > I observed gcc 2.95.4 and gcc 3.1 interpret (or maybe optimize) the > following code differently (CFLAGS=-O): > > int main(void) > { > unsigned char i = 127; > printf("%d\n", ((char)(i << 1)) / 2); > return 0; > } I think GCC 3.1 does a logical right shift by one to optimize the division by two instead of an arithmetic right shift. ciao, -robert To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Re: moused(8): char signed-ness problem with gcc 3.1
gcc 3.1 simply defaults to unsigned chars. 127 << 1 = 254; 254 / 2 = 127. My machine is too slow to test this expeditiously, but I'm trying adding "#define DEFAULT_SIGNED_CHAR 1" into freebsd-native.h . Bill To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
Re: moused(8): char signed-ness problem with gcc 3.1
Akinori MUSHA wrote: > I observed gcc 2.95.4 and gcc 3.1 interpret (or maybe optimize) the > following code differently (CFLAGS=-O): > > int main(void) > { > unsigned char i = 127; > printf("%d\n", ((char)(i << 1)) / 2); > return 0; > } > Cool... > gcc 2.95.4 says it's -1, Promotion of operand to int; conversion to lvalue type after the operation. > whereas gcc 3.1 says it's 127. Promotion of operand to lvalue type. > On FreeBSD > char should be signed, so I suspect it's a (optimization) bug of gcc > 3.1 which should be fixed. Or we'll have to do a mass audit of the > whole src tree to check and fix the similar expressions. Technically, I think, because of the parenthesis, that GCC 2.95 is right, and GCC 3.1 is wrong. Given that the conversion to "char" is done prior to the division, it should happen first. >From the assembly, it looks like 3.1 is treating "/2" as ">>1", and illegally canceling out the "<<1" with the ">>1" *before* the conversion. Or maybe it's the conversion to int that happens on the stack value for a %d argument to printf... Maybe one of out C standards people can define when the conversion is defined to occur, so we can get a real ruling. Note that: int main(void) { unsigned char i = 127; printf("%d\n", (char)((i << 1) / 2)); return 0; } ...yields 127 on gcc 2.95, so it's definitely order of conversion being totally screwed by gcc 3.1. Basically, it's assuming commutability where it's not present. > In any case, this behavior makes moused(8) return a stupid value of > 127 when you roll the mouse wheel up under ps/2-sysmouse-intellimouse > protocol. Attached is a patch that makes the whole expression look > more logical and works around the above behavior at the same time. [ ... ] > - act->dz = ((char)(pBuf[5] << 1) + (char)(pBuf[6] << 1))/2; > + act->dz = ((char)(pBuf[5] << 1) + (char)(pBuf[6] << 1)) >> 1; This is *soo* counter intuitive that it's evil! -- Terry To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message
moused(8): char signed-ness problem with gcc 3.1
I observed gcc 2.95.4 and gcc 3.1 interpret (or maybe optimize) the following code differently (CFLAGS=-O): int main(void) { unsigned char i = 127; printf("%d\n", ((char)(i << 1)) / 2); return 0; } gcc 2.95.4 says it's -1, whereas gcc 3.1 says it's 127. On FreeBSD char should be signed, so I suspect it's a (optimization) bug of gcc 3.1 which should be fixed. Or we'll have to do a mass audit of the whole src tree to check and fix the similar expressions. In any case, this behavior makes moused(8) return a stupid value of 127 when you roll the mouse wheel up under ps/2-sysmouse-intellimouse protocol. Attached is a patch that makes the whole expression look more logical and works around the above behavior at the same time. -- / /__ __Akinori.org / MUSHA.org / ) ) ) ) / FreeBSD.org / Ruby-lang.org Akinori MUSHA aka / (_ / ( (__( @ iDaemons.org / and.or.jp "Somewhere out of a memory.. of lighted streets on quiet nights.." Index: moused.c === RCS file: /home/ncvs/src/usr.sbin/moused/moused.c,v retrieving revision 1.55 diff -u -r1.55 moused.c --- moused.c28 Apr 2002 11:59:30 - 1.55 +++ moused.c15 May 2002 17:16:40 - @@ -1972,7 +1972,7 @@ act->dx =(char)(pBuf[1]) + (char)(pBuf[3]); act->dy = - ((char)(pBuf[2]) + (char)(pBuf[4])); if (rodent.level == 1) { - act->dz = ((char)(pBuf[5] << 1) + (char)(pBuf[6] << 1))/2; + act->dz = ((char)(pBuf[5] << 1) + (char)(pBuf[6] << 1)) >> 1; act->button |= ((~pBuf[7] & MOUSE_SYS_EXTBUTTONS) << 3); } break; To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message