From: steve@taumet.com (Steve Clamage)
Subject: Re: Register declaration
Keywords: ambiguity,register,declarations
Organization: TauMetric Corporation
Date: Tue, 7 Apr 1992 18:54:22 GMT

bodo@clipper.ingr.com (Bodo Parady) writes:


>A question has arisen regarding the use of the register declaration. 
>Two interpretations of the following statement are possible:
>	register float *x;
>Is this symbolically equivalent to:
>        register float *x;     is the same as:     (register float)*x
>Or:
>        register float *x      is the same as:     (float)*(register x)

There is only one interpretation.  "register" is a storage class
which applies to the object being declared (the "declarator").  It is
not part of the type.  The declaration can be written as either of
	register float *x;
	float register *x;

>The context of the "register" dilemma is the following code fragement: 
>>     register float *x, *y, *z, *end_z;
>>     for (; z <= end_z; ) {
>>       *x += (*z++) * (*y++);
>>       *x += (*z++) * (*y++);
>>       *x += (*z++) * (*y++);
>>       *x += (*z++) * (*y++);
>>       }
>>     *x = *x + 1.0;

>The problem for any optimizer is that the addressess (x, y, z, send_z)
>can be ambiguous (for example z could equal x, etc).  Does "register" 
>signify that the addresses x,y,z, and send_z are disambiguated?

Huh?  The four variables x, y, z, end_z are each separately declared.
No correct compiler could possibly allocate them to the same location
unless analysis showed they had disjoint lifetimes.  (In such a case
no conforming program could detect that they shared storage.)  In this
example, they share live regions, and must be allocated separately.

"register" is a hint to the compiler that the variables are heavily
used, and that it might be beneficial to assign them to registers.
The compiler may take or ignore the hint, but it may not use the hint
as an excuse to generate incorrect code.

Now maybe you are really talking about the "aliasing" problem, where
the addresses POINTED-TO by the variables might be the same.  A
conforming compiler must make the pessimistic assumption that the
variables might point to the same location, unless some language
extension is provided to indicate that they don't.  (Or when analysis
shows that they can't point to the same location.)  The pessimistic
assumption generally means larger and slower runtime code.

Some compilers elect to make the optimistic assumption that no
aliasing takes place, and generate small and fast code.  I suppose
the vendors believe that it is better to generate wrong answers
quickly than correct answers slowly.  Such compilers are not
conforming, but generally have some option to tell them to make
pessimistic assumptions about aliasing.

In my view, such compilers are dangerous.  I don't believe the
programmer should have to request specifically via a language
extension or compiler flag that correct code be generated.

Here's a suggestion for compiler reviewers writing for magazines,
and for vendors of test suites:  Include a piece of code with
pointer aliasing, and see which compilers get it right.
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com
Vice Chair, ANSI C++ Committee, X3J16