Go interfaces with small value types

Hi, all,

I thought that when I first started learning about how Go interfaces work, that I saw somewhere that if the value is small enough to fit into the second uintptr of the interface{}, that the value itself would be put into there instead of creating a pointer to the value and putting the pointer into that position. For example, I thought that this:

n := int32(1)
var i interface{} = n
data := *((*[2]uintptr)(unsafe.Pointer(&i)))
fmt.Println(data)

Would output:

[975264 1]

But instead I see:

[975264 272826108]

Where the second number is the pointer to an int32 with the actual value: 1.

I’m Googling now to see where I first read that, and haven’t yet found it. My question isn’t “why” because the behavior I’m seeing is consistent with what I’d expect when the value in the interface is a larger struct that cannot fit into the uintptr. My question is: “Am I just totally wrong about small values being put into the interface{} itself? Has it always been this way?” And also, “Am I even testing this correctly?”

EDIT 1: Russ Cox’s page on Go interfaces from 2009-12-1: https://research.swtch.com/interfaces

1 Like

It used to be as you say. It isn’t any more. I don’t fully recall the reason for the change, but it happening somewhere around the GC becoming fully precise comes to mind.

1 Like

Thanks, Jakob, I’ll keep an eye out to see if I can find the reason.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.