That’s actually what I meant to indicate in the last paragraph (emphasis added 
by me):

> The code in the Reddit post takes advantage of the fact that the last 
> increment of the C-style loop can be observed outside the loop,

But thanks for providing a clarification. I see now it has not been clear to 
everyone.

> On Wed, Jul 26, 2017 at 08:44:46AM -0700, Christoph Berger wrote:
> 
>>> someone shared [this question](
>>> https://www.reddit.com/r/golang/comments/6paqc0/bug_that_caught_me_with_range/)
>>>  
>>> on reddit. I must say, that I'm surprised by the behavior myself. I would 
>>> have expected
>>> for i = range v
>>> to be semantically equivalent to
>>> for i = 0; i < len(v); i++
>>> and don't really understand the reasoning behind choosing different 
>>> semantics. Note, that the difference only exists, if i is declared outside 
>>> of the loop, that is, this is solely about the behavior after exiting the 
>>> loop-body.
>>> 
>>> I'd greatly appreciate some explanation :)
>> An attempt to explain this by looking at the C-style loop only:
>> 
>> The classic C-style for loop
>> 
>> for i:=0; i<len(v); i++ {...}
>> 
>> is equivalent to
>> 
>> for i:=0; i<len(v); {
>>    // do something with i
>>    i++ // This is always the very last statement in the loop body
>> }
>> 
>> The loop body runs from 0 to len(v)-1 only, because the last increment of i 
>> to len(v) stops the loop, and no further iteration occurs. The code in the 
>> loop body never sees i being set to len(v). 
>> 
>> And that's the same behavior as with the range operator. 
>> 
>> The code in the Reddit post takes advantage of the fact that the last 
>> increment of the C-style loop can be observed outside the loop, for 
>> detecting if the loop stopped early. This is a neat side effect that is not 
>> possible with the range operator.
> 
> I would point out that both Axel and you are off a tiny bit from what
> actually happens ;-)
> 
> In a for loop which uses a short variable declaration, that variable's
> scope is confined to the for *statement* itself, and is also visible in
> the loop's body because its scope is defined to be nested in that of the
> loop statement.  This means in a loop like
> 
>  for i := 0; i < len(s); i++ {
>  }
> 
> the variable "i" is not accessible after the closing brace.
> 
> The actual "problem" stated in that Reddit post is different: it uses a
> variable defined outside the "for" loop:
> 
>  var i int
>  for i = 0; i < len(v); i++ {
>  }
> 
> As you can see, the loop merely uses that variable; it existed before
> the loop and continued to live on after it finished executing.
> 
> To recap what others have already written, since the for loop's post
> statement is defined to be executed after each execution of the body
> (unless it was exited by means of executing `break` or `return`), that
> 
>  i++
> 
> statement gets executed, the condition evaluates to false, and the loop
> exits -- with the variable "i" having the value equal to len(v).
> 
> One could do
> 
>  var x int
> 
>  for i := 0; i < len(v); i, x = i+1, x*2 {
>  }
> 
> and get even more interesting effect on the variable "x" after the loop
> finishes executing ;-)
> 
> -- 
> You received this message because you are subscribed to a topic in the Google 
> Groups "golang-nuts" group.
> To unsubscribe from this topic, visit 
> https://groups.google.com/d/topic/golang-nuts/Xi6W3H5mlto/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to 
> golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to