apm233m@vaxc.cc.monash.edu.au (06/26/91)
My question is: is there a patch for Turbo C++ v1.0 to fix the following
code generation bug?
The bug concerns the code generated for a right shift of longs.
The following short program demonstrates the bug.
main()
{
long bad=-2, good=-4;
printf("Is this true?: -1=%ld, -1=%ld\n", bad >> 1, good >> 2);
}
My copy of TC++ generates an .exe which produces:
Is this true?: -1=2147483647, -1=-1
This bug occurs only for shifts of longs, and only if the shift is
by the constant "1". It is a bug in the generated code; the preprocessor
does not have the bug and therefore cannot be used to detect the bug.
The actual generated code is:
shr ax,1
rcr dx,1
whereas the correct code would be:
sar ax,1
rcr dx,1
--
---------------
Bill Metzenthen
Mathematics Department
Monash University
Australia
bhoughto@bishop.intel.com (Blair P. Houghton) (06/27/91)
In article <1991Jun26.155139.86965@vaxc.cc.monash.edu.au> apm233m@vaxc.cc.monash.edu.au writes: >My question is: is there a patch for Turbo C++ v1.0 to fix the following >code generation bug? If it were ANSI C, I'd point to the part where it says bitwise operations are undefined when performed on signed operands... However, it's Turbo C, with which I have nil experience (up until now, that is...:-)). You might try casting them as `unsigned long', but that's iffy, too. --Blair "Where no man has gone before..."
kers@hplb.hpl.hp.com (Chris Dollin) (06/27/91)
Blair P. Houghton says: If it were ANSI C, I'd point to the part where it says bitwise operations are undefined when performed on signed operands... Which bit is that? [My draft says in 3.3.7 under ``semantics'' that (in E1 >> E2) ``if E1 has a signed type and a negative value, the resulting value is implementation-defined'' (not ``undefined''). For E1 << E2, it just says that it's ``E1 left-shifted E2 positions'', and details the value for E1 of unsigned type, but seems to be silent on E1 of signed type. I had though I had a ``latest draft'', but now I look at the date it's Dec 88. Another change?] -- Regards, Chris ``GC's should take less than 0.1 second'' Dollin.
mouse@thunder.mcrcim.mcgill.edu (der Mouse) (06/29/91)
In article <1991Jun26.155139.86965@vaxc.cc.monash.edu.au>, apm233m@vaxc.cc.monash.edu.au writes: > My question is: is there a patch for Turbo C++ v1.0 to fix the > following code generation bug? > The bug concerns the code generated for a right shift of longs. > The following short program demonstrates the bug. > main() { > long bad=-2, good=-4; > printf("Is this true?: -1=%ld, -1=%ld\n", bad >> 1, good >> 2); > } > My copy of TC++ generates an .exe which produces: > Is this true?: -1=2147483647, -1=-1 > This bug occurs only for shifts of longs, and only if the shift is by > the constant "1". It is a bug in the generated code; the > preprocessor does not have the bug and therefore cannot be used to > detect the bug. The New Testament says, on page 206 (A7.8, Shift Operators): The value of E1>>E2 is E1 right-shifted E2 bit positions. The right shift is equivalent to division by 2^E2 if E1 is unsigned or if it has a non-negative value; otherwise the result is implementation-defined. Now, you say it's a C++ compiler, not a C compiler. I don't know what, if anything, the definition of C++ says about this. But since you posted to comp.lang.c instead of (! not in addition to!) comp.lang.c++, I figure a C answer is fair game. And from that perspective, your compiler is entirely within its rights to do a logical shift instead of an arithmetic shift, even if it does this only when the shift count is 1. der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu
eychaner@suncub.bbso.caltech.edu (Another casualty of applied metaphysics.) (06/30/91)
mouse@thunder.mcrcim.mcgill.edu (der Mouse) writes: >The New Testament says, on page 206 (A7.8, Shift Operators): > > The value of E1>>E2 is E1 right-shifted E2 bit positions. The > right shift is equivalent to division by 2^E2 if E1 is unsigned > or if it has a non-negative value; otherwise the result is > implementation-defined. OK, I'm sorry, I just had to post on this one, since this, then, creates a problem for me (someday my code will break). I have the following piece of code (Please understand that this is just a fragment; any unwanted errors are probably my fault, and some things are the way they are for reasons I don't care to go into.): short a_250K_array[]; /* The big array */ int bit_shift, /* Bit shift */ array_size, i; /* Array size and index */ for (i = 0; i < arraysize; i++) { a_250K_array[i] >>= bit_shift; /* I shouldn't index the array like this; but it makes the code clearer */ } What I want is to divide each member of the 250K short array by 2^bit_shift. The 250K array contains both positive and negative numbers. In Vax C 3.0 (it's not the greatest, but it's adequate, OK?) section 7.5.7 SEEMS to guarantee that this works by filling the vacated bits with a copy of E1's sign bit (and indeed, from experience, it does work as expected). However, someday (dream on) Vax C might become ANSI standard, and I will need to change the way I do this. (Here, portability isn't a big issue, but having a system upgrade break code might be.) One qualifier: this loop must be FAST. And in my experience (so far), a_250K_array[i] /= (1 << bit_shift); isn't as fast as the first method. Is this the only ANSI legal way to do what I want to do? AARGH! This particular section of the standard puzzles me; why impose this seemingly unnecessary constraint on the shift operators? (Five thousand people will now write me explaining in great detail why it is necessary.) -G. ****************************************************************************** Glenn Eychaner - Big Bear Solar Observatory - eychaner@suncub.bbso.caltech.edu "There is no monopoly of common sense / On either side of the political fence" -Sting, "Russians"
eychaner@suncub.bbso.caltech.edu (Another casualty of applied metaphysics.) (06/30/91)
I (Another casualty of applied metaphysics.) write: >mouse@thunder.mcrcim.mcgill.edu (der Mouse) writes: >>The New Testament says, on page 206 (A7.8, Shift Operators): >> >> The value of E1>>E2 is E1 right-shifted E2 bit positions. The >> right shift is equivalent to division by 2^E2 if E1 is unsigned >> or if it has a non-negative value; otherwise the result is >> implementation-defined. > >I have the following piece of code (shortened version): > >short a_250K_array[]; >int bit_shift, array_size, i; >for (i = 0; i < arraysize; i++) a_250K_array[i] >>= bit_shift; > >What I want is to divide each member of the 250K short array by 2^bit_shift. >The 250K array contains both positive and negative numbers. > >In Vax C 3.0 section 7.5.7 SEEMS to guarantee that this works by filling the >vacated bits with a copy of E1's sign bit (and indeed, from experience, it >does work as expected). >One qualifier: this loop must be FAST. And in my experience (so far), > > a_250K_array[i] /= (1 << bit_shift); > >isn't as fast as the first method. Is this the only ANSI legal way to do what >I want to do? (Actually, the first method appears to be ANSI legal but not necessarily completely portable, as the result is "implementation-defined" rather than "undefined".) No one has yet suggested a better method than this on a machine with undefined signed shifts; any takers? >This particular section of the standard puzzles me; why impose this seemingly >unnecessary constraint on the shift operators? (Five thousand people will now >write me explaining in great detail why it is necessary.) Thanks to: dik@cwi.nl, raymond@math.berkeley.edu, and wirzeniu@cc.helsinki.fi for their timely responses. It is necessary beacuse some machines (i.e. Crays) have no "shift-and-sign-fill" operator (and creating one creates a large drop in performance). Note that the ANSI standard says "implementation-defined" rather than "undefined"; I can always hope that DEC continues to define the implementation in a reasonable, backward-compatible way. (Dream on again?) -G. ****************************************************************************** Glenn Eychaner - Big Bear Solar Observatory - eychaner@suncub.bbso.caltech.edu "There is no monopoly of common sense / On either side of the political fence" -Sting, "Russians"