3 ms·
> The other thing I see that fools people with experience from other languages is that the "nil" pointer is not the same thing as a NULL pointer in C. In C, the
by dbaupp 9y ago
> The other thing I see that fools people with experience from other languages is that the "nil" 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.
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.
If you're talking about interfaces, then, there's actually two sorts of nil interfaces: interfaces where the data pointer is nil, and interfaces that are completely nil (both data and type/interface-info pointers).
func main() {
var x *int
var y interface{} = x
var z interface{}
fmt.Printf("%v, %v, %T, %v, %T, %v", x, y, y, z, z, y == z)
// <nil>, <nil>, *int, <nil>, <nil>, false
}
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++ could make it legal to call methods on nil/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.
> they are not bad in the C sense that any attempt to touch one is a segfault
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/reproducible way.
- int_19h 9y ago> 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. The point, I think, is that this type information is carried only at compile time on the binding, not at runtime on the value itself. If you have multiple aliases to the same null value (e.g. via references or pointers to pointers), the behavior will change depending on which alias is used. Not so in Go. Of course, this is also true for non-null values in C++, when methods are non-virtual, so...
- dbaupp 9y agoThe rest of my comment fairly specifically covered that: Go nil pointers don't have runtime types (like C), Go nil interfaces sometimes do. In any case, pointers to pointers with different types seem likely to be a strict aliasing violation in C.
- int_19h 9y ago> In any case, pointers to pointers with different types seem likely to be a strict aliasing violation in C. Surprisingly, no, at least not in similar context. For example, it's perfectly legal to cast a pointer to a struct to a pointer to its first member - it's specifically guaranteed that this works as you'd expect. This is often used when emulating single-inheritance OOP in C - your "base class" is then the first member of struct type, and this lets you upcast and downcast with impunity.
- dbaupp 9y agoCasting pointer-to-struct to pointer-to-field is fine, yes, but is it legal to cast pointer-to-pointer-to-struct to pointer-to-pointer-to-field? (I genuinely don't know the answer to this.) The former results in a new (temporary or otherwise) value with a new static static type, independent of the original, while the latter does not, and so is the interesting one. In any case, note that Go also has something a little similar, with its anonymous fields approach to composition. However, that's not still at all the main point: there's actually not that much difference between how C and Go behave with compiletime/runtime types.
- int_19h 9y agoTo the best of my language lawyering knowledge, no, such a cast wouldn't be legal, and would indeed be a strict aliasing violation.