The empty struct

Source:
(1)The empty struct (Must Read)
(2)Padding is hard (Must Read)
(3)Go Data Structures

Digest:
1. Width :
-- Width describes the number of bytes of storage an instance of a type occupies. As a process's address space is one dimensional, i think width is a more apt than size.
2. Struct:
Structs provide a more flexible way of defining composite types, whose width is the sum of the width of the constituent types, plus padding.
3. An empty struct:
The empty struct has a width of zero. It occupies zero bytes of storage.
As the empty struct consumes zero bytes, it follows that it needs no padding. Thus a struct comprised of empty structs also consumes no storage.
4. The usage of an empty struct:
(1) signal channel -- done := make(chan struct{});
(2) singletons -- Where an OOP programmer would use some variant of the Singleton design pattern, to ensure that only one instance of his class is created, in Go you can use an empty struct, and store all your data in global variables. There will only be one instance of the type, since all empty structs are interchangeable. Of course you could just use global variables and functions instead, unless you need to fulfill an interface. But if you need to fulfill an interface, it's quite useful. You see this pattern a lot in thego.text/encoding packages.
5. Padding is hard:
This is a story about trying to speed up the Go compiler. Since Go 1.5 we've had the great concurrent GC, which reduces the cost of garbage collection, but no matter how efficient a garbage collector is, it doesn't make allocations free of cost.
The specific allocation i was targeting was the obj.Prog structure which represents a quasi machine code instruction late in the compile cycle. As you can see, for this compilation (which was cmd/compile/internal/gc) obj.Prog values constitute 34.72% of the total allocations for this program -- reducing the size of obj.Prog will pay off in real terms.
6. Alignment and padding:
The reason for the difference between the 32 bit and 64 bit answers is alignment. The Go spec says the address of a struct's fields must be naturally aligned. So on a 64 bit machine, the address of any uint64 field must be a multiple of 8 bytes.
On 32 bit machines, word boundaries occur every 4 bytes.
7. An empty struct at the bottom of the type:
What is it about the presence of an empty struct at the bottom of the type that causes it to increase the size of the struct?
The answer is that while empty struct{} values consume no storage, you can take their address. That is, if you have a type:

type T struct {
	X uint32{}
	Y struct{}
}
var t T

It is perfectly valid to take the address of t.Y, and as such, the address of t.Y would point beyond the end of the struct!
Now, Go code cannot do anything useful with this invalid pointer, but as it is a pointer, the garbage collector has to follow it, and that may lead it to access unmapped memory or dereference an invalid pointer.
The fix for this is detailed in issue 9401 and delivered in Go 1.5. In summary, zero sized values, like struct{} and [0]byte occurring at the end of a structure are assumed to have a size of one byte.
...
Fortunately this last issue can be corrected by moving the zero field to the top of the structure, restoring the original sizes we observed in Go 1.4.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值