compiler: alignof [0]func() = 1

In the go protobuf code, a pattern is used to statically prevent
comparable structs by embedding:

```
type DoNotCompare [0]func()

type message struct {
  DoNotCompare
  data *uint32
}
```

Previously, sizezof(message{}) is 2 words large, but it only needs to be
1 byte.  Making it be 1 byte allows protobufs to compile slightly more
(though not all the way).
This commit is contained in:
Steven Kabbes
2022-05-17 21:23:43 -07:00
committed by Ron Evans
parent 995e815b63
commit 4c7449efe5
2 changed files with 16 additions and 0 deletions
+10
View File
@@ -52,6 +52,12 @@ func main() {
println("\nvalues of interfaces")
var zeroSlice []byte
var zeroFunc func()
// by embedding a 0-array func type in your struct, it is not comparable
type doNotCompare [0]func()
type notComparable struct {
doNotCompare
data *int32
}
var zeroMap map[string]int
var zeroChan chan int
n := 42
@@ -170,6 +176,10 @@ func main() {
assertSize(reflect.TypeOf(new(int)).Size() == unsafe.Sizeof(new(int)), "*int")
assertSize(reflect.TypeOf(zeroFunc).Size() == unsafe.Sizeof(zeroFunc), "func()")
// make sure embedding a zero-sized "not comparable" struct does not add size to a struct
assertSize(reflect.TypeOf(doNotCompare{}).Size() == unsafe.Sizeof(doNotCompare{}), "[0]func()")
assertSize(unsafe.Sizeof(notComparable{}) == unsafe.Sizeof((*int32)(nil)), "struct{[0]func(); *int32}")
// Test that offset is correctly calculated.
// This doesn't just test reflect but also (indirectly) that unsafe.Alignof
// works correctly.