<story><title>Understand Go pointers</title><url>https://dave.cheney.net/2017/04/26/understand-go-pointers-in-less-than-800-words-or-your-money-back</url></story><parent_chain><item><author>jerf</author><text>Since you sort of ask: Go pointers themselves are not that special, because in a GC&amp;#x27;ed language with no pointer arithmetic they&amp;#x27;re really just a map&amp;#x2F;territory-type distinction, but there are some syntax affordances that can make them briefly more confusing than they appear.&lt;p&gt;For method calls and field accesses, Go fuzzes whether you have an object or a pointer by making the &amp;quot;.&amp;quot; operator work on both, rather than C&amp;#x27;s &amp;quot;.&amp;quot; vs &amp;quot;-&amp;gt;&amp;quot; distinction. Since it&amp;#x27;s never ambiguous, it&amp;#x27;s just pointless overhead to make the programmer worry about that. It can also be slightly confusing that the method itself can control whether it receives a pointer, so you can call object.Method on a concrete object, but Method will receive &amp;amp;object. As a professional programmer I appreciate not being bothered with this unambiguous detail that the language can easily handle for me, but it can confuse people in the early going, which is a legitimate criticism. (I still come down in favor of doing what it is doing, but it is a legitimate drawback.)&lt;p&gt;The other thing I see that fools people with experience from other languages is that the &amp;quot;nil&amp;quot; pointer is not the same thing as a NULL pointer in C. In C, the NULL pointer is simply a zero with no type information connected to it. In Go, pointers are actually (type, address) tuples, so a nil pointer to a custom struct is actually (pointer CustomStruct [1], nil), which means that the runtime is capable of correctly resolving methods on nil pointers and that you can therefore write methods that work on nil pointers. Nil pointers are still bad because they are a value added to all pointer types by the act of taking a pointer that you can&amp;#x27;t control, you get it whether you like it or not, &lt;i&gt;but&lt;/i&gt; they are not bad in the C sense that any attempt to touch one is a segfault.[2]&lt;p&gt;That&amp;#x27;s about all that matters in normal Go programming.&lt;p&gt;[1]: Asterisk is confusing HN&amp;#x27;s italicization there.&lt;p&gt;[2]: Which is I think an important aspect of understanding the &amp;quot;billion dollar mistake&amp;quot;, by the way; it is easy to deconstruct that mistake as being two mistakes rolled in to one, which may perhaps explain why it was such a big mistake.</text></item><item><author>nottorp</author><text>I clicked the article thinking that Go pointers are something special... but this seems targeted at the &amp;quot;programmers&amp;quot; who only know javascript...</text></item></parent_chain><comment><author>dbaupp</author><text>&lt;i&gt;&amp;gt; The other thing I see that fools people with experience from other languages is that the &amp;quot;nil&amp;quot; pointer is not the same thing as a NULL pointer in C. In C, the NULL pointer is simply a zero with no type information connected to it. In Go, pointers are actually (type, address) tuples, so a nil pointer to a custom struct is actually (pointer CustomStruct [1], nil), which means that the runtime is capable of correctly resolving methods on nil pointers and that you can therefore write methods that work on nil pointers.&lt;/i&gt;&lt;p&gt;This paragraph seems, at best, misleading. C NULLs are not untyped either (using the same asterisk-avoidance as you): `T pointer x = NULL` means x is a NULL pointer with type T. Similarly, a Go `var x pointer T = nil` is a plain pointer-sized object with all bytes zero, just like C.&lt;p&gt;If you&amp;#x27;re talking about interfaces, then, there&amp;#x27;s actually two sorts of nil interfaces: interfaces where the data pointer is nil, and interfaces that are completely nil (both data and type&amp;#x2F;interface-info pointers).&lt;p&gt;&lt;pre&gt;&lt;code&gt;  func main() {
  	var x *int
  	var y interface{} = x
  	var z interface{}
  	fmt.Printf(&amp;quot;%v, %v, %T, %v, %T, %v&amp;quot;, x, y, y, z, z, y == z)	
  	&amp;#x2F;&amp;#x2F; &amp;lt;nil&amp;gt;, &amp;lt;nil&amp;gt;, *int, &amp;lt;nil&amp;gt;, &amp;lt;nil&amp;gt;, false
  }
&lt;/code&gt;&lt;/pre&gt;
In any case, for a comparison to C, Go is fairly similar: you can call functions with nil pointers in either, just fine, and dereferencing one is bad (the badness is far more controlled in Go, but see below). For a more reasonable comparison about methods, C++ &lt;i&gt;could&lt;/i&gt; make it legal to call methods on nil&amp;#x2F;NULL pointers, and, like a completely-nil interface, crash when calling a virtual method (i.e. one that requires dereferencing a nil pointer to get the function pointer), but optimisations win out.&lt;p&gt;&lt;i&gt;&amp;gt; they are not bad in the C sense that any attempt to touch one is a segfault&lt;/i&gt;&lt;p&gt;Note that this has nothing to do with nil pointers storing runtime types (even if they stored them) or anything like that: the Go language just (sensibly) decided to not have undefined behaviour with nil pointers, requiring that implementations handle them in a reliable&amp;#x2F;reproducible way.</text></comment>
<story><title>Understand Go pointers</title><url>https://dave.cheney.net/2017/04/26/understand-go-pointers-in-less-than-800-words-or-your-money-back</url></story><parent_chain><item><author>jerf</author><text>Since you sort of ask: Go pointers themselves are not that special, because in a GC&amp;#x27;ed language with no pointer arithmetic they&amp;#x27;re really just a map&amp;#x2F;territory-type distinction, but there are some syntax affordances that can make them briefly more confusing than they appear.&lt;p&gt;For method calls and field accesses, Go fuzzes whether you have an object or a pointer by making the &amp;quot;.&amp;quot; operator work on both, rather than C&amp;#x27;s &amp;quot;.&amp;quot; vs &amp;quot;-&amp;gt;&amp;quot; distinction. Since it&amp;#x27;s never ambiguous, it&amp;#x27;s just pointless overhead to make the programmer worry about that. It can also be slightly confusing that the method itself can control whether it receives a pointer, so you can call object.Method on a concrete object, but Method will receive &amp;amp;object. As a professional programmer I appreciate not being bothered with this unambiguous detail that the language can easily handle for me, but it can confuse people in the early going, which is a legitimate criticism. (I still come down in favor of doing what it is doing, but it is a legitimate drawback.)&lt;p&gt;The other thing I see that fools people with experience from other languages is that the &amp;quot;nil&amp;quot; pointer is not the same thing as a NULL pointer in C. In C, the NULL pointer is simply a zero with no type information connected to it. In Go, pointers are actually (type, address) tuples, so a nil pointer to a custom struct is actually (pointer CustomStruct [1], nil), which means that the runtime is capable of correctly resolving methods on nil pointers and that you can therefore write methods that work on nil pointers. Nil pointers are still bad because they are a value added to all pointer types by the act of taking a pointer that you can&amp;#x27;t control, you get it whether you like it or not, &lt;i&gt;but&lt;/i&gt; they are not bad in the C sense that any attempt to touch one is a segfault.[2]&lt;p&gt;That&amp;#x27;s about all that matters in normal Go programming.&lt;p&gt;[1]: Asterisk is confusing HN&amp;#x27;s italicization there.&lt;p&gt;[2]: Which is I think an important aspect of understanding the &amp;quot;billion dollar mistake&amp;quot;, by the way; it is easy to deconstruct that mistake as being two mistakes rolled in to one, which may perhaps explain why it was such a big mistake.</text></item><item><author>nottorp</author><text>I clicked the article thinking that Go pointers are something special... but this seems targeted at the &amp;quot;programmers&amp;quot; who only know javascript...</text></item></parent_chain><comment><author>pcwalton</author><text>&amp;gt; Which is I think an important aspect of understanding the &amp;quot;billion dollar mistake&amp;quot;, by the way; it is easy to deconstruct that mistake as being two mistakes rolled in to one, which may perhaps explain why it was such a big mistake.&lt;p&gt;If it&amp;#x27;s two mistakes, it&amp;#x27;s one big one (having null pointers at all) and one tiny one (the fact that calling methods on null pointers is undefined behavior in C++). The latter is yet another C++ gotcha, but not nearly as pernicious as the former, which causes nearly all the null pointer-related bugs in the wild.</text></comment>