<p>I have been writing a compiler in Go and I have come across a very unusual issue. </p>
<p>Here is the code I am debugging:</p>
<pre><code>if t.SubType != nil {
println("1: subtype of "+token+" is "+t.SubType.Name)
}
ic.ExpressionType = t
if t.SubType != nil {
println("2: subtype of "+token+" is now "+t.SubType.Name)
}
</code></pre>
<p><del>An example context can be found <a href="https://play.golang.org/p/Zi2EO0RLC4" rel="nofollow">here</a> (Although this works as expected)</del></p>
<p>I would expect that the assignment would not change the pointer value of t.SubType. The thing is, it does somehow.
The problematic output I am getting is:</p>
<pre><code>1: subtype of l is Int
2: subtype of l is now list
</code></pre>
<p>When I am expecting:</p>
<pre><code>1: subtype of l is Int
2: subtype of l is now Int
</code></pre>
<p>When I comment out the line
ic.ExpressionType = t
Then I get the result I expected.</p>
<p><del>Am I missing something here? Or could it be a bug with the Go compiler itself?</del></p>
<p>Edit: it turns out 't.SubType' is pointing at ic.ExpressionType. </p>
<hr/>**评论:**<br/><br/>google_you: <pre><p>come up with actual testcase that exhibits the strange behavior (assignment changes value of right hand side).</p></pre>Splizard: <pre><p>I have the actual compiler which I am writing.</p></pre>vAltyR47: <pre><p>But we can't see your actual code, and the example you've given us works properly. This is not an actual test case because it doesn't exhibit the behavior you're describing.</p>
<p>If you can't reproduce the bug reliably, there's nothing we can do to help you diagnose what's happening.</p>
<p>EDIT: Thinking about it a different way, there's something different between your code and the example you've given us. Did you write the playground example from scratch, or did you copy-paste your code in and it magically worked? If the former, then likely you have a typo in your code.</p></pre>Sythe2o0: <pre><p>Are there other goroutines running?</p></pre>Splizard: <pre><p>I have not started any with the "go" keyword, the program should be running sequentially.</p></pre>whizack: <pre><p>i mean the clear path to debugging this is finding assignments of the subtype 'list'. it seems that ic.ExpressionType = t is just a red herring. </p>
<p>Something is concurrently modifying the SubType pointer and you just so happen to have noticed it at this location.</p></pre>Splizard: <pre><p>There is only one goroutine running. The only concurrent logic would be from the Garbage Collector.</p></pre>whizack: <pre><p>it seems you have already figured it out, but yeah the next step would be to check your pointers for shenanigans.</p></pre>nhooyr: <pre><p>Don't use <code>println</code>. Use <code>fmt.Println</code>, see the comment on <a href="https://golang.org/pkg/builtin/#println" rel="nofollow">https://golang.org/pkg/builtin/#println</a></p></pre>Splizard: <pre><p>Yea, It's for debugging purposes, the code does not normally have println</p></pre>ChristophBerger: <pre><p>I think the more important point is the last half sentence of the <code>println</code> doc: </p>
<blockquote>
<p>it is not guaranteed to stay in the language.</p>
</blockquote>
<p>I usually use <code>davegch/spew</code> for quick, readable data dumps. Easy to add, easy to remove (as, like with <code>println</code>, you would not use <code>spew.Dump()</code> for anything other than debugging.)</p>
<p>Also a great debugging help: <a href="https://godoc.org/github.com/kr/pretty" rel="nofollow"><code>kr/pretty</code></a>, a pretty printer that also can diff data structures. (Buz, if you read this: Thanks for pointing me to this one.)</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传