Non Zero Sized Empty Struct

I’m trying to understand Golang’s struct memory layout. As far as I know, Go has some similarity with C in term of the memory layout, every type has size and alignment and some padding will be added into the struct to make sure every field positioned in the correct alignment. But, I can’t explain this one case:

// Available at:
package main

import (

type A struct {
	a int32
	b int32
	c struct{}

type B struct {
	c struct{}
	a int32
	b int32

func main() {
	fmt.Println(unsafe.Sizeof(A{})) // prints 12
	fmt.Println(unsafe.Sizeof(B{})) // prints 8

As far as I know, struct{} has 0 size and aligned to 1 byte, but why does struct A’s size is 12, whereas struct B is 8? It seems, if a struct is ended with an empty struct, they will add some padding in the end of the struct. But, I’m not sure why does Go do this. Is my hypothesis true? And if it’s true, what’s the reason?

Here you go:

Also from that answer:

And why the compiler doesn’t automatically do something about this:

1 Like

From the articles above, it seems the problem is because of the GC. If we don’t pad the last struct{} with [1]byte, it is possible to get the address of the last struct which points to invalid memory region. But, I still don’t get it why having a pointer to invalid memory region is not ok. Since the size is zero, deferencing it is like no-op, we can just return struct{}{} without actually fetch it from memory. And since the GC have the type information, they can deduce that those particular memory region is of type struct{} and shouldn’t scan when doing GC.
One case that I think can be problematic is when we have []A, The &slice_of_a[0].c might point to the &slice_of_a[1], and we end up with one address that have two types, one struct{}, one A. But, even when this happen, I don’t see why it can be harmful to the GC.
Am I missing something?

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