randy@gtx.com (Randy D. Miller) (11/02/88)
I've seen conflicting information about the shift operator in cases where operand2 is exactly equal to the number of bits in the object. E.g., with a 32 bit int, what must the following do? int n; n <<= 32; K&R 1st ed. seems to indicate the operation is undefined, but does the proposed standard change this? -- Randy D. Miller (602) 870-1696 GTX Corp., 8836 N. 23rd Ave., Phoenix, AZ 85021 {cbosgd,decvax,hplabs,amdahl,nsc}!sun!sunburn!gtx!randy
guy@auspex.UUCP (Guy Harris) (11/02/88)
> int n; > n <<= 32; > >K&R 1st ed. seems to indicate the operation is undefined, but does >the proposed standard change this? No. If you depend on it doing something in particular, you will lose. There exist quite common machines on which shift counts are not taken modulo the word size (68K) and quite common machines on which it is (80386), and chances are the compiler will just generate a shift instruction and not add extra code to check whether the shift count is larger than the word size.
crossgl@ingr.UUCP (Gordon Cross) (11/02/88)
In article <786@gtx.com>, randy@gtx.com (Randy D. Miller) writes: > I've seen conflicting information about the shift operator in cases > where operand2 is exactly equal to the number of bits in the object. > E.g., with a 32 bit int, what must the following do? > > int n; > n <<= 32; > > K&R 1st ed. seems to indicate the operation is undefined, but does > the proposed standard change this? K&R still applies. The proposed ANSI standard states: "If the right operand is negative or is greater than or equal to the width in bits of the promoted left operand, the result is implementation defined." Note the phrase "promoted left operand". This means that (assuming 16-bit shorts and 32-bit ints) the value of the expression "shortvar << 16" IS defined and has the same value as "shortvar * 0x10000"! Gordon Cross Intergraph Corp. Huntsville, AL
gwyn@smoke.BRL.MIL (Doug Gwyn ) (11/03/88)
In article <786@gtx.com> randy@gtx.UUCP (Randy D. Miller) writes: > n <<= 32; >K&R 1st ed. seems to indicate the operation is undefined, but does >the proposed standard change this? It's undefined because the intention is that a raw machine shift instruction be usable to implement this, and usually such a shift count cannot be represented in the instruction. I did see an architecture once that was unable to represent a 0 shift count, or rather you could build such an instruction but it didn't work right! However, the proposed C standard allows <<0 and >>0. (By the way, if the count is written as a constant, the compiler can sometimes use alternate code sequences, e.g. n <<= 16 becomes SWAP_HALVES CLEAR_LOWER and n <<= 100 could become CLEAR It is when a general expression is used for the count that things get interesting.)
blm@cxsea.UUCP (Brian Matthews) (11/03/88)
Randy D. Miller (randy@gtx.UUCP) writes: |I've seen conflicting information about the shift operator in cases |where operand2 is exactly equal to the number of bits in the object. |E.g., with a 32 bit int, what must the following do? | int n; | n <<= 32; |K&R 1st ed. seems to indicate the operation is undefined, but does |the proposed standard change this? From section 3.3.7 "Bitwise shift operators" of the ANSI draft standard, in the first paragraph under Semantics: "...If the value of the right operand is negative or greater than or equal to the width in bits of the promoted left operand, the behavior is undefined." -- Brian L. Matthews blm@cxsea.UUCP ...{mnetor,uw-beaver!ssc-vax}!cxsea!blm +1 206 251 6811 Computer X Inc. - a division of Motorola New Enterprises
scjones@sdrc.UUCP (Larry Jones) (11/03/88)
In article <786@gtx.com>, randy@gtx.com (Randy D. Miller) writes: > I've seen conflicting information about the shift operator in cases > where operand2 is exactly equal to the number of bits in the object. > K&R 1st ed. seems to indicate the operation is undefined, but does > the proposed standard change this? Nope, the draft says "If the value of the right operand is negative or is greater than or equal to the width in bits of the promoted left operand, the behavior is undefined." ---- Larry Jones UUCP: uunet!sdrc!scjones SDRC scjones@sdrc.uucp 2000 Eastman Dr. BIX: ltl Milford, OH 45150 AT&T: (513) 576-2070 "Save the Quayles" - Mark Russell
friedl@vsi.COM (Stephen J. Friedl) (11/03/88)
In article <786@gtx.com>, randy@gtx.com (Randy D. Miller) writes: > I've seen conflicting information about the shift operator in cases > where operand2 is exactly equal to the number of bits in the object. > E.g., with a 32 bit int, what must the following do? > > int n; > n <<= 32; > > K&R 1st ed. seems to indicate the operation is undefined, but does > the proposed standard change this? 3.3.7 Bitwise shift operators. Syntax: shift_expression: additive_expression shift_expression << additive_expression shift_expression >> additive_expression Constraints: Each of the operands shall have integral type. Semantics: The integral promotions are performed on each operand. If the value of the right operand is negative or is greater than or equal to the width in bits of the promoted left operand, the behavior is undefined. -- Steve Friedl V-Systems, Inc. +1 714 545 6442 3B2-kind-of-guy friedl@vsi.com {backbones}!vsi.com!friedl attmail!vsi!friedl ----Nancy Reagan on 120MB SCSI cartridge tape: "Just say *now*"----
root@libove.UUCP (Jay M. Libove) (11/05/88)
From article <786@gtx.com>, by randy@gtx.com (Randy D. Miller): > I've seen conflicting information about the shift operator in cases > where operand2 is exactly equal to the number of bits in the object. > E.g., with a 32 bit int, what must the following do? > > int n; > n <<= 32; Boy am I confused. Looking at the above, I read it to be "shift an n-bit integer n bits left" which would presumably have the following effect: (let n=8 for simplicity) i = abcdefgh shift left one i = bcdefgh0 shift left one i = cdefgh00 ... shift left the last time i = 00000000 Now, why is there any question as to the result? (One machine test: SCO Xenix 286 v2.2.1 results 0 from int x; x=0xffff; x <<= 16; printf("%d\n",x); ) -- Jay Libove ARPA: jl42@andrew.cmu.edu or libove@cs.cmu.edu 5731 Centre Ave, Apt 3 BITnet: jl42@andrew or jl42@drycas Pittsburgh, PA 15206 UUCP: uunet!nfsun!libove!libove or (412) 362-8983 UUCP: psuvax1!pitt!darth!libove!libove
chris@mimsy.UUCP (Chris Torek) (11/08/88)
In article <192@libove.UUCP> root@libove.UUCP (Jay M. Libove) writes: >Looking at the above, I read it to be "shift an n-bit integer n bits left" >... Now, why is there any question as to the result? Because different machines implement shift-left differently. >(One machine test .... Try a better test. #define BITS_PER_CHAR 8 /* needed below */ int fn(); main() { int x = ~0; x <<= fn(sizeof(x)); printf("result of %d << %d is %d\n", ~0, fn(sizeof(x)), x); exit(0); } /* * You may have to put fn() in a separate file if your compiler is * overly clever. */ int fn(sz) int sz; { return (sz * BITS_PER_CHAR); } On the VAX, the result of shifting by the (not known to be constant) value 32 is the same as the result of shifting by zero, because the VAX looks only at the 5 lowest order bits of the shift count. It does this so that right shifts can be done with negative left shifts. (Note that, since this is an arithmetic shift and not a rotate, it still checks the sign bit of the shift count to see whether to propagate the sign bit of the original value in a rightward shift.) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
guy@auspex.UUCP (Guy Harris) (11/09/88)
>Now, why is there any question as to the result?
Because:
1) the intent was that shifts be implemented using the machine's
shift instructions, with as little extra decoration as
possible;
and
2) some machines take the shift count modulo the word size,
and others don't, so some machines, when told to shift left
(word size) bits, will shift (word size) bits,
clearing the word, and others will shift left 0 bits.
The language spec specifically allows for this, by not specifying what
happens if you have a shift count >= (word size).
gwyn@smoke.BRL.MIL (Doug Gwyn ) (11/10/88)
In article <192@libove.UUCP> root@libove.UUCP (Jay M. Libove) writes: >Now, why is there any question as to the result? Rewrite the example as int n, s; s = 32; /* ... */ n << s; Now tell us what machine instructions will be generated for "n << s". Then look up the behavior of those instructions when s==32.
mouse@mcgill-vision.UUCP (der Mouse) (11/15/88)
In article <14414@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes: > In article <192@libove.UUCP> root@libove.UUCP (Jay M. Libove) writes: >> Looking at the above, I read it to be "shift an n-bit integer n bits >> left" ... Now, why is there any question as to the result? > Because different machines implement shift-left differently. >> (One machine test .... > Try a better test. > [sample program, with shift count not known at compile time] > On the VAX, the result of shifting by the (not known to be constant) > value 32 is the same as the result of shifting by zero, because the > VAX looks only at the 5 lowest order bits of the shift count. What sort of VAX is this you're talking about, Chris? The Gray Book, revision 6.1, dated 20 May 1982, says that the ASHL shift count is a signed byte. Then, under "Notes:", it says 2. If cnt GTR 32 (ASHL) or cnt GTR 64 (ASHQ) the destination operand is replaced by 0. 3. If cnt LEQ -31 (ASHL) or cnt LEQ -63 (ASHQ) all the bits of the destintation operand are copies of the sign bit of the source operand. I assume note 2 is supposed to read GEQ instead of GTR, or 31 and 63 instead of 32 and 64. I tried this and (a) the compiler used an ashl to do the shift and (b) it worked the way the book says: 1<<32==0. Machines were a 750 and a MicroVAX-II. If a right shift is simply a negative left shift, and it uses only the low five bits, could you explain the difference between i<<30 and i>>2 to me, please? der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu
chris@mimsy.UUCP (Chris Torek) (11/15/88)
In article <1354@mcgill-vision.UUCP> mouse@mcgill-vision.UUCP (der Mouse) writes: >What sort of VAX is this you're talking about, Chris? I must have been thinking about the ROTL instruction... (Okay, the VAX tries to do << `correctly'.) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris