Help understanding a nil that's not a nil

197 views
Skip to first unread message

John Graham-Cumming

unread,
Sep 7, 2012, 7:50:26 AM9/7/12
to golang-nuts
I've isolated an odd situation in my program to a minimal test case:

package main

import (
"fmt"
"net"
"crypto/tls"
)

func main() {
var c net.Conn

c, err := tls.Dial("tcp", "www.jgc.org:80", nil)

fmt.Printf("%v %v\n", c, err)

if c == nil {
fmt.Printf("Nil\n")
} else {
fmt.Printf("Not nil\n")
}
}

This attempts to make a TLS connection to my web server on port 80
(this is done to _force_ a TLS error return from tls.Dial). The
output of this program is peculiar:


<nil> local error: record overflow
Not nil

When c is printed with %v it is reported as 'nil'. But when tested
with the if c == nil it is not nil. What's happening here?

John.

Miek Gieben

unread,
Sep 7, 2012, 7:52:31 AM9/7/12
to golang-nuts
[ Quoting <jgra...@gmail.com> in "[go-nuts] Help understanding a nil ..." ]
c is a net.Conn, so it's not a pointer and cannot be nil.
If you need to compare it, you need to use the natural null value
of net.Conn (whatever that may be).

Therefor its easier to test against the err value.

grtz Miek
signature.asc

John Graham-Cumming

unread,
Sep 7, 2012, 7:56:02 AM9/7/12
to golang-nuts
On Sep 7, 12:52 pm, Miek Gieben <m...@miek.nl> wrote:
> c is a net.Conn, so it's not a pointer and cannot be nil.
> If you need to compare it, you need to use the natural null value
> of net.Conn (whatever that may be).
>
> Therefor its easier to test against the err value.

OK, I sort of understand. But inside net.Dial if there's an error it
will return nil for the net.Conn. What is the meaning of that nil?

John.

David Symonds

unread,
Sep 7, 2012, 7:56:05 AM9/7/12
to golang-nuts
On Fri, Sep 7, 2012 at 9:52 PM, Miek Gieben <mi...@miek.nl> wrote:

> c is a net.Conn, so it's not a pointer and cannot be nil.
> If you need to compare it, you need to use the natural null value
> of net.Conn (whatever that may be).

tls.Dial returns a *tls.Conn, not a net.Conn. You are assigning a nil
*tls.Conn to a net.Conn, and so you have a nil pointer inside the
interface value. That is not nil (c != nil), but when you print it out
it is nil.

http://golang.org/doc/go_faq.html#nil_error

John Graham-Cumming

unread,
Sep 7, 2012, 7:57:35 AM9/7/12
to golang-nuts
On Sep 7, 12:56 pm, David Symonds <dsymo...@golang.org> wrote:
> http://golang.org/doc/go_faq.html#nil_error

Thanks for pointing me to the FAQ. Makes sense now.

John.

Miek Gieben

unread,
Sep 7, 2012, 7:58:01 AM9/7/12
to David Symonds, golang-nuts
[ Quoting <dsym...@golang.org> in "Re: [go-nuts] Help understanding a ..." ]
That indeed makes more sense.

Disregard my mail (SMTP REVOKE)


Regards,

--
Miek Gieben http://miek.nl
signature.asc

RoboTamer

unread,
Sep 7, 2012, 7:58:22 AM9/7/12
to golan...@googlegroups.com

Miek Gieben

unread,
Sep 7, 2012, 8:01:14 AM9/7/12
to golang-nuts
[ Quoting <dsym...@golang.org> in "Re: [go-nuts] Help understanding a ..." ]
But suppose you do want to keep testing against the zero value of c, what
do you need to type?

if ( c == &tls.Conn{} ) { ... }

Or something like that?
signature.asc

RoboTamer

unread,
Sep 7, 2012, 8:04:17 AM9/7/12
to golan...@googlegroups.com
Well the interface is returning two values, if you wont to check the error. you have to address the error 

Miek Gieben

unread,
Sep 7, 2012, 8:06:16 AM9/7/12
to golan...@googlegroups.com
[ Quoting <grue...@gmail.com> in "Re: [go-nuts] Help understanding a ..." ]
> Well the interface is returning two values, if you wont to check the error. you
> have to address the error

interface -> function, you mean.

And you're right, but that does not answer my question :)
signature.asc

David Symonds

unread,
Sep 7, 2012, 8:10:25 AM9/7/12
to golang-nuts
On Fri, Sep 7, 2012 at 10:01 PM, Miek Gieben <mi...@miek.nl> wrote:

> But suppose you do want to keep testing against the zero value of c, what
> do you need to type?
>
> if ( c == &tls.Conn{} ) { ... }

if c.(*tls.Conn) == nil {

http://play.golang.org/p/rJxhp92G4k

Miek Gieben

unread,
Sep 7, 2012, 8:11:53 AM9/7/12
to golang-nuts
[ Quoting <dsym...@golang.org> in "Re: [go-nuts] Help understanding a ..." ]
brrr, *ugly*
signature.asc

Patrick Mylund Nielsen

unread,
Sep 7, 2012, 8:14:09 AM9/7/12
to golang-nuts
so don't write code that relies on testing whether a pointer inside an interface is nil

roger peppe

unread,
Sep 7, 2012, 8:25:54 AM9/7/12
to David Symonds, golang-nuts
On 7 September 2012 13:10, David Symonds <dsym...@golang.org> wrote:
> On Fri, Sep 7, 2012 at 10:01 PM, Miek Gieben <mi...@miek.nl> wrote:
>
>> But suppose you do want to keep testing against the zero value of c, what
>> do you need to type?
>>
>> if ( c == &tls.Conn{} ) { ... }
>
> if c.(*tls.Conn) == nil {

alternatively

if c == (*tls.Conn)(nil) {
Reply all
Reply to author
Forward
0 new messages