# [Rd] reference counting bug related to break and next in loops

Wacek Kusnierczyk Waclaw.Marcin.Kusnierczyk at idi.ntnu.no
Wed Jun 3 11:06:02 CEST 2009

```Wacek Kusnierczyk wrote:
>
> a simplified example may help to get a clear picture:
>
>     i = 1; y = 1:3;
>     (while(TRUE) {
>        y[i] = 0
>        if (i == 2) break
>        i = i + 1
>        y })
>     # 0 0 3
>
>     i = 1; y = 1:3;
>     (while(TRUE) {
>        y[i] = 0
>        if (i == 2) break
>        i = i + 1
>        y + 0 })
>     # 0 2 3
>
> the test on i is done after the assignment to y[i].  when the loop
> breaks, y is 0 0 3, and one might expect this to be the final result.
> it looks like the result is the value of y from the previous iteration,
> and it does not seem particularly intuitive to me.  (using common sense,
> i mean;  an informed expert on the copy-when-scared semantics may have a
> different opinion, but why should a casual user ever suspect such magic.)
>
> anyway, i'd rather expect NULL to be returned.  for the oracle,
> ?'while', says:
>
> "'for', 'while' and 'repeat' return the value of the last expression
> evaluated (or 'NULL' if none was), invisibly. [...]  'if' returns the
> value of the expression evaluated, or 'NULL' if none was. [...]  'break'
> and 'next' have value 'NULL', although it would be strange to look for a
> return value."
>
> when i is 2, i == 2 is TRUE.  hence, if (i == 2) break evaluates to
> break.  break evaluates to NULL, breaks the loop, and the return value
> should be NULL.  while it is, following the docs, strange to have q =
> while(...) ... in the code, the result above is not compliant with the
> docs at all -- seems like a plain bug.  there is no reason for while to
> return the value of y, be it 0 0 3 or 0 2 3.
>

somewhat surprising to learn,

i = 1
y = 1:3
(while (TRUE) {
y[i] = 0
if (i == 2) { 2*y; break }
i = i + 1
y })
# 0 0 3

where clearly the last expression evaluated (before the break, that is)
is 2*y -- or?

vQ

```