Why emptyCtx use type int rather than struct{}

In the $SDKPath\go1.19.2\src\context\context.go, the define of emptyCtx is:

// An emptyCtx is never canceled, has no values, and has no deadline. It is not
// struct{}, since vars of this type must have distinct addresses.
type emptyCtx int

I don’t understand the meaning of this comment “It is not struct{}, since vars of this type must have distinct addresses.” Why does it say that different addresses are needed here? The same address doesn’t seem to cause any problems. If struct{} can be used here, it should save a lot of memory.
Such as

type emptyCtx struct{}

Since the empty Struct has width 0 it does not need any space. But a thing which needs no space cannot have its own address in memory. Otherwise it would need to block at least one byte of memory, so nothing else can use the same address.

So empty structs share the same address:

package main

import "fmt"

type emptyStruct struct{}

func main() {
	var a emptyStruct
	var b emptyStruct

	fmt.Printf("a= %p b= %p", &a, &b) // will print the same address for a and b
}

If you want to check if a context is “the empty context” you need a distinct address. Otherwise every other context which is an empty struct would also return true for ctx == emptyContext which is not what we want.

1 Like

Hi @polarbear122, welcome to the forum.

Genuine question: How many empty contexts (Background() or TODO()) does the average Go app instantiate throughout its lifetime? I daresay the number is rarely high enough to worry about memory consumption.


Edited to add: This should have been a reply to the original post

1 Like

To elaborate further on @falco467’s answer, vif emptyCtx was a struct{}, its String() method might return the wrong context name, because the first case would always match:

func (e *emptyCtx) String() string {
	switch e {
	case background:
		return "context.Background"
	case todo:
		return "context.TODO"
	}
	return "unknown empty Context"
}

var (
	background = new(emptyCtx)
	todo       = new(emptyCtx)
)

Output:

context.Background
context.Background

(Playground)

2 Likes

Thank you very much for your reply. The example you provided clearly demonstrates the rationality of emptyCtx’s design.

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