[comp.std.c] Shifting question

rbutterworth@watmath.waterloo.edu (Ray Butterworth) (07/19/88)

In article <60290@sun.uucp>, guy@gorodish.Sun.COM (Guy Harris) writes:
> > action of doing:
> > 	x >>= 16; x>>= 16;
> > better be the same as:
> > 	x = x>>32;
> 
> Perhaps they *should*; however, neither the K&R nor the January 11 ANSI C draft
> specifications for the language require this.  If you think that they should, I
> suggest you lobby the ANSI C committee.

I can see why the Committee should NOT require that (for n>0)
"x >>= n;"  be the same as  "while (n--!=0) x>>=1;".

Imagine a machine with 16 bit words and a logical right shift
instruction that only looks at the lowest 4 bits of the shift size.

"x >>= n;" could simply grab the 4 lower bits of "n" to determine
the size of the shift.  But if the Standard required the requested
behaviour, the compiler would have to generate a lot of extra code
for every shift to change it to a store-zero whenever "n" is
greater than 15. e.g.

LOAD n       Put the shift size into the register.
CMPI #15     Is it bigger than 15?
TLTZ +3
LRS  x           No, shift x right by lower 4 bits of the register
TRA  +2
STZ  x           Yes, so store zero

instead of simply

LOAD n
LRS  x     Shift x right by lower 4 bits of n

No, I don't know of any such machine.
Yes, I know it would be more efficient to change positions of the
shift and store-zero cases.

davidsen@steinmetz.ge.com (William E. Davidsen Jr) (07/25/88)

henry@utzoo.uucp (Henry Spencer) writes:

| You have an out-of-date draft, I believe.  The second-public-comment draft
| (I haven't seen the third yet) explicitly forbids sizeof in this context.

  I believe what I have is current. I got it a week ago and it's marked
as THIRD public review. The many references were all based on that
draft.

  Another note, from the sizeof (3.3.3.4) section, line 23.
    Constraints
    ===========
    
      The _sizeof_ operator shall not be applied to an expression
    function type or an incomplete type, to the parenthesized name
    of such a type, or to an lvalue that designates a bitfield
    object.


Chris Tokek said that there was a obscure phrase which
disallowed use of sizeof in the preprocessor, but 3.8.1 on the
#if says that the 2nd argument is a constant expression, and 3.4
(constant expressions) says:

    Constraints
    ===========
    
      Constant expression shall not contain assignment, increment,
    decrement, function call, or comma operators, except when they
    when they are contained within the operand of a sizeof operator.
    
  This is the only reference to constant expression in the index. If
the semantics of the #if say that the first field is a constant
expression, and the definition of constant expression specifically
includes sizeof, either sizeof is legal in the expression of #if, or
perhaps the phrase is a bit too obscure.

  I didn't think this was legal, but after some time checking the
standard I thank that the standard *seems* to say that it is.

  Since this discussion has gotten split between comp.std.c, comp.lang.c and
comp.arch, I have directed followup to comp.std.c, since the question
has changed to a standards issue.
-- 
	bill davidsen		(wedu@ge-crd.arpa)
  {uunet | philabs | seismo}!steinmetz!crdos1!davidsen
"Stupidity, like virtue, is its own reward" -me

cudcv@warwick.ac.uk (Rob McMahon) (07/26/88)

In article <19962@watmath.waterloo.edu> rbutterworth@watmath.waterloo.edu (Ray Butterworth) writes:
|> In some article, someone whose name is lost in the mists of time writes:
|> > action of doing:
|> > 	x >>= 16; x>>= 16;
|> > better be the same as:
|> > 	x = x>>32;
|
|I can see why the Committee should NOT require that (for n>0)
|"x >>= n;"  be the same as  "while (n--!=0) x>>=1;".
|
|Imagine a machine with 16 bit words and a logical right shift
|instruction that only looks at the lowest 4 bits of the shift size.
|...
|No, I don't know of any such machine.

Okay, to make this concrete, have a look at a Gould sometime.  This hasn't
actually got any `shift by variable' instructions, only shift by constant.  A
shift by variable is done by constructing an instruction in a register and
then executing it.  At the moment this requires AND-OR-EXECUTE, the people who
are suggesting fixing the behaviour when `n' is < 0 or >= bits per word would
force the compiler to add tests for n >= 32 or n < 0 to this.
-- 
UUCP:   ...!mcvax!ukc!warwick!cudcv	PHONE:  +44 203 523037
JANET:  cudcv@uk.ac.warwick             ARPA:   cudcv@warwick.ac.uk
Rob McMahon, Computing Services, Warwick University, Coventry CV4 7AL, England

paul@hcr.UUCP (Paul Jackson) (07/28/88)

In article <11637@steinmetz.ge.com> davidsen@crdos1.UUCP (bill davidsen) writes:
>[Much stuff on the legality of sizeof in the preprocessor

>Chris Tokek said that there was a obscure phrase which
>disallowed use of sizeof in the preprocessor, but 3.8.1 on the
>-- 
>	bill davidsen		(wedu@ge-crd.arpa)
>  {uunet | philabs | seismo}!steinmetz!crdos1!davidsen
>"Stupidity, like virtue, is its own reward" -me

	There is a footnote (number 74) on page 84 of the draft that explains
the reasoning of the committee

"Because the controlling constant expression is evaluated during translation
phase 4, all identifiers either are or are not macro names - there simply are
no keywords, enumeration constants, and so on."

	Because of the phases of translation, the whole question of whether
sizeof is legal just doesn't arise.  Admittedly one has to read the standard
very carefully to realize this, but that is why the footnote was added.

					Paul Jackson
					(utzoo|utcsri)!hcr!paul