Why this global variable assignment is deleted in the infinite loop?

105 views
Skip to first unread message

WX Lai

unread,
Mar 11, 2021, 12:12:59 PM3/11/21
to golang-nuts
Hi, 


The assignment of the global variable `isRunning` in function `fg1` does not work at all.
In fact, the assignment is deleted in the assembly (see the comment of the link above).

Why the compiler works like this? It disappeared after the process `short circuit`, after all `isRunning` is used in `main` and `fg2`, making `fg2` never return.

Thank you!

Jan Mercl

unread,
Mar 11, 2021, 12:19:30 PM3/11/21
to WX Lai, golang-nuts
The compiler is correct. The change to isRunning is not observable in
the goroutine that executes fg1() so there's no need to actually
update the variable.

Axel Wagner

unread,
Mar 11, 2021, 1:21:42 PM3/11/21
to WX Lai, golang-nuts
You need to either use a mutex (or some other synchronization primitive) or atomic accesses.

On Thu, Mar 11, 2021 at 6:12 PM WX Lai <0xbi...@gmail.com> wrote:
--
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...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/729079c1-6af7-4261-872e-bb65e76734bbn%40googlegroups.com.

WX Lai

unread,
Mar 12, 2021, 1:42:54 AM3/12/21
to golang-nuts
Thank you. Yes, the article introducing the go memory model gave precise conditions. 
However, if fg1 comes like:
func fg1() {
    for x := uint64(0); x < math.MaxUint64; x++ {
        isRunning--
    }
}
or 
func fg1() {
    if isRunning > 0 {
        isRunning = 0
    }
}
Then the fg2() will return very quickly.

Axel Wagner

unread,
Mar 12, 2021, 2:10:23 AM3/12/21
to WX Lai, golang-nuts
Hi,

I'm sorry. I don't know why the compiler decides to delete the assignment in one case but not the other. I doubt there is a better answer than "it decides to drop it, because it's faster that way" and "it doesn't drop it, because it doesn't realize that it can, for some reason".

However, I also don't understand why it's relevant. Both versions of the code are wrong and buggy. And it turns out that this version of this compiler surfaces the bug in one case, but not the other. A different compiler, or a different version of the same compiler, might surface the bug in neither or both cases instead. So if you are asking because you want to rely on one behavior or the other, you are (IMO) making a mistake - you are introducing compiler-version specific, mysterious bugs. If you are asking because you observe similar effects in a non-buggy program which you are trying to optimize, we should be talking about that non-buggy program instead.

--
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...@googlegroups.com.

WX Lai

unread,
Mar 12, 2021, 6:45:51 AM3/12/21
to golang-nuts
I am grateful for your apply. The code came from an article introducing go memory model and we tested it and tried to understand the cause just because of curiosity.
Thanks the buggy code since now we totally understand when and how to deal with concurrency in Go more.
Reply all
Reply to author
Forward
0 new messages