Do pointer receiver methods need to be checked for nil?

1,324 views
Skip to first unread message

shinya sakae

unread,
Nov 25, 2021, 11:39:52 PM11/25/21
to golang-nuts
Hi.
I've been using Go for a while now, and I've noticed something.
Do pointer receiver methods need to be checked for nil?
In the standard package, it may or may not be checked.
I'd like to hear your opinions.

Roland Müller

unread,
Nov 26, 2021, 2:23:30 AM11/26/21
to shinya sakae, golang-nuts
Definitely yes. I just sent a message in another thread in this discussion group

BR,
Roland

Quoting myself:

Obviously, even just calling a "methods" of some struct instance that is not initialized succeeds in Go. A panic occurs only when the program tries to derefer nil pointer: 

'func (ev *Event) do()' only uses the pointer but does not derefer it. Thus, no panic.

Here 'func (ev Event) do2()' derefers nil pointer already before call. Panic in main.main()

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x47f812]

goroutine 1 [running]:
main.main()
	/tmp/sandbox1681946220/prog.go:14 +0x112

Here 'func (ev *Event) getS()' derefers the pointer. Panic happens inside the main.getS()
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x47f8d4]

goroutine 1 [running]:
main.(*Event).getS(0x4b2a40)
	/tmp/sandbox1571083836/prog.go:35 +0x14


--
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/8bada92b-f179-4133-adcf-0cf971671b00n%40googlegroups.com.

Axel Wagner

unread,
Nov 26, 2021, 2:46:42 AM11/26/21
to shinya sakae, golang-nuts
In my opinion, this depends on exactly one thing: I nil is expected to be a valid value (and I need to dereference it to implement that valid behavior), I will check for nil to trigger that behavior. An example is a linked list or tree data-structure, where calling a method on nil can signal "end of list" and simplify code, e.g.: https://go.dev/play/p/3iBnERuId_v

Otherwise, I don't check. If nil is not an expected value, calling a method on a nil-pointer is a bug and it will panic as soon as it is dereferenced. Panicing on a bug is the correct behavior. Usually, there isn't anything do to but panic in that case anyways - I could do `if p == nil { panic("nil pointer") }`, but that doesn't add any benefit, the panic will happen either way.

Some people will advocate to return an error when calling a method on a nil-pointer which doesn't expect that, if it already returns an error (and letting it panic otherwise). Personally, I strongly disagree with this philosophy. To me, a panic is meant to be communicated to the *programmer*, to debug (and hence it produces a stacktrace), while an error is meant to be communicated to the *user* of a program. In particular, an error should be fixable without touching the program. "File config.json does not exist" is a clear error, which the user of a program can interpret and fix and which is not dependent on the internal validity of the program. "(*Foo).Bar called on a nil-pointer" is something they can do nothing about - especially not without a stack trace". Hence, returning an error on a nil-pointer is converting a useful signal into a useless one, frustrating both the user and the programmer, who has then to try and fix a bug, without any debugging-context.

--

w54n

unread,
Nov 29, 2021, 1:16:53 PM11/29/21
to golang-nuts
I would like to share two posts from Cheney which could help you visualise situations of nil receivers, and if those should be checked or not by your program


One of the previous examples given to you could be simply fixed by using the zero value of the type.

It all boils down to how you want your program to behave and what you expect from it. Your question is about design and designing a program which intrinsically handles state without boilerplate code is a key.
Reply all
Reply to author
Forward
0 new messages