[comp.lang.c] register variable???

sklee@pompeii.SRC.Honeywell.COM (Sungkee Lee) (09/08/89)

#include <stdio.h>
  int  list[5] = {0, 1, 2, 3, 4};

main()
{
  register int  i;

  printf("list = %d %d %d %d %d\n",
	 list[0], list[1], list[2], list[3], list[4]);
  i = 0;
  while (i < 4)  list[i] = list[++i];
  printf("list = %d %d %d %d %d\n",
	 list[0], list[1], list[2], list[3], list[4]);
}
  
Above program gave me the result,

list = 0 1 2 3 4
list = 0 1 2 3 4.

However, if I define "int i" instead of "register int i",
the result is

list = 0 1 2 3 4
list = 1 2 3 4 4.

Is this the way register variable is designed?
Or, is this compiler error? I ran this program on Sun 3/60?

cpcahil@virtech.UUCP (Conor P. Cahill) (09/09/89)

In article <30585@srcsip.UUCP>, sklee@pompeii.SRC.Honeywell.COM (Sungkee Lee) writes:
>   printf("list = %d %d %d %d %d\n",
> 	 list[0], list[1], list[2], list[3], list[4]);
>   i = 0;
>   while (i < 4)  list[i] = list[++i];
                   ^^^^^^^^^^^^^^^^^^^^
This is an undefined operation due to the use of i on both sides with 
an auto increment on the right.  There is no definition of the value of
i on the left and that value may change due to the declaration of i
as a register type or a non-register.  

> Is this the way register variable is designed?
> Or, is this compiler error? I ran this program on Sun 3/60?

It is neither.  It is a problem with the code.

chris@mimsy.UUCP (Chris Torek) (09/09/89)

In article <30585@srcsip.UUCP> sklee@pompeii.SRC.Honeywell.COM (Sungkee Lee)
writes:
>  while (i < 4)  list[i] = list[++i];

USE LINT!!!!!

Sheesh.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

darcy@bbm.UUCP (D'Arcy Cain) (09/12/89)

In article <30585@srcsip.UUCP> sklee@srcsip.UUCP () writes:
>  while (i < 4)  list[i] = list[++i];
I have always been too scared to take a chance on this type of code.  It
seems to me that it is subject to compiler interpretation as to when the
++ operator is applied.  Example on the first iteration:

    list[0] = list[1];
or
    list[1] = list[1];

I don't actually know if either is guaranteed by some standard but even
if it is I wouldn't want to depend on such a guarantee on a specific
compiler having seen how some of them implement "standards".  I would
use the following replacement for the above line:

	for (i = 0; i < 4; i++) list[i] = list[i + 1];
which keeps the increment out of the loop.

D'Arcy J.M. Cain
(darcy@bbm, darcy@cain)

perry@ccssrv.UUCP (Perry Hutchison) (09/13/89)

In article <19487@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:

> In article <30585@srcsip.UUCP> sklee@pompeii.SRC.Honeywell.COM (Sungkee Lee)
> writes:
> >  while (i < 4)  list[i] = list[++i];
> 
> USE LINT!!!!!
> 
> Sheesh.

Provided he has it on his system and understands the (frequently cryptic)
messages it produces.  Let's answer the fellow's question:

The assignment produces "undefined results" because there is no guarantee
as to when "side effects" (like ++) happen.  According to the definition
of prefix ++, the right-hand operand of = must use the incremented value of
i as the subscript; however the left-hand operand may evaluate the address
into which the assignment will take place either before or after the right-
hand expression stores the incremented value into i.  It appears that, in
this implementation, that decision is different depending on whether i is
a register variable.

diamond@csl.sony.co.jp (Norman Diamond) (09/13/89)

In article <30585@srcsip.UUCP> sklee@srcsip.UUCP () writes:

>  i = 0;
>  while (i < 4)  list[i] = list[++i];
>
>... if I define "int i" instead of "register int i",
>the result is [different]

This question seems to come up twice a week now.

list    [    i    ]    =      list    [    ++    i    ]
        [b]  [a]       [last] [4]     [3]  [2]   [1]

There are several possible sequences of evaluation.
Operation [1] (fetching value of i) must precede [2] (increment).
Operation [2] must precede [3] (array indexing) because it is a
pre-increment operation.
Operation [3] must precede [4] (fetching value of array element).
Operation [a] (fetching value of i) must precede [b] (array indexing).
All of the above must precede the assignment [last].

Notice what isn't specified?  Does operation [a] come before or after
operation [2]?  [a] could even come before [1] or after [4].

On the right-hand side, the rules of the language specify that
list[++i] uses the new value of i.  On the left-hand side, the rules
do not specify whether list[i] uses the old or new value of i.

If you were lucky, the compiler would call a random number generator
to decide whether to use the old value of i or the new value.
Unfortunately it chose one way for "register" and the other way
for non-"register".  Therefore you were confused, and you thought
that "register" makes a difference.  It does not.

--
-- 
Norman Diamond, Sony Corporation (diamond@ws.sony.junet)
  The above opinions are inherited by your machine's init process (pid 1),
  after being disowned and orphaned.  However, if you see this at Waterloo or
  Anterior, then their administrators must have approved of these opinions.

gwyn@smoke.BRL.MIL (Doug Gwyn) (09/13/89)

In article <789@bbm.UUCP> darcy@bbm.UUCP (darcy) writes:
>I don't actually know if either is guaranteed by some standard but even
>if it is I wouldn't want to depend on such a guarantee on a specific
>compiler ...

That's a wise attitude.  The harder one leans on the language, the more
likely that some compiler will do the wrong thing.

chris@mimsy.UUCP (Chris Torek) (09/13/89)

>>In article <30585@srcsip.UUCP> sklee@pompeii.SRC.Honeywell.COM (Sungkee Lee)
>>wrote:
>>>  while (i < 4)  list[i] = list[++i];

>In article <19487@mimsy.UUCP> I griped:
>>USE LINT!!!!!
>>Sheesh.

In article <615@ccssrv.UUCP> perry@ccssrv.UUCP (Perry Hutchison) writes:
>Provided he has it on his system

In this case, he did (he said `a Sun'; all Suns have lint).

>and understands the (frequently cryptic) messages it produces.

This is a somewhat better objection.  However, in this case, the message
from lint is of the form:

	warning: i evaluation order undefined.

That, plus different outputs from different compilations, should be enough
for anyone to figure out that, well, the evaluation order is undefined and
in fact does vary.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris