Sep 25, 2018

[Go][c++] padding

[golang]
  • zero length type, i.e, sizeof(T) == 0, consumes 1 byte if it's the last data member inside the struct type.
    If it's _not_ the last data member inside the struct type, it's size remains 0.
    why? it's about taking the zero length type's instance's address.
    We don't want the zero length type instance act as the last data member inside a type refers to other memory location.
    The zero length type instance act as data member inside a type which is not at the last location has 0 length.
  • ref:
    https://dave.cheney.net/2015/10/09/padding-is-hard
    http://www.catb.org/esr/structure-packing/
  • zero length type in namespace's instance's addresses are the same.
    (this is why C++ zero length type's instance always consumes 1 byte for differentiating the instance's address.)
  • https://dave.cheney.net/2014/03/25/the-empty-struct#comment-2815
    * It's not true that "a value must be aligned in memory to a multiple of its width."
    * Each type has another property, its alignment. Alignments are always powers of two.
    * The alignment of a basic type is usually equal to its width, but the alignment of a struct is the maximum alignment of any field, and the alignment of an array is the alignment of the array element.
    * The maximum alignment of any value is therefore the maximum alignment of any basic type.
    * Even on 32-bit systems this is often 8 bytes, because atomic operations on 64-bit values typically require 64-bit alignment.
    * To be concrete, a struct containing 3 int32 fields has alignment 4 but width 12.
    * It is true that a value's width is always a multiple of its alignment.
    * One implication is that there is no padding between array elements.
    package main
    
    import "unsafe"
    
    type Fun struct {
    	i  *int
    	bl bool
    	b  byte
    }
    
    func main() {
    
    	a := [2]Fun{Fun{}, Fun{}}
    	println(unsafe.Sizeof(Fun{})) // 16
    	println(unsafe.Sizeof(a))     // 32
    
    	b := [2]*int{nil, nil}
    	println(unsafe.Sizeof(b)) // 16
    }
    
  • https://golang.org/ref/spec#Size_and_alignment_guarantees
    * A struct or array type has size zero if it contains no fields (or elements, respectively) that have a size greater than zero.
    * Two distinct zero-size variables may have the same address in memory. 
  • runtime.zerobase https://github.com/golang/go/blob/383b447e0da5bd1fcdc2439230b5a1d3e3402117/src/runtime/malloc.go#L813
    All zero sized instance has this same address at run-time.
    Found through cmd:
    $ go tool nm
package main

import (
 "fmt"
 _ "unsafe"
)

//go:linkname zerobase runtime.zerobase
var zerobase uintptr

func main() {
 var s struct{}
 var a [42]struct{}

 fmt.Printf("zerobase = %p\n", &zerobase)
 fmt.Printf("       s = %p\n", &s)
 fmt.Printf("       a = %p\n", &a)
}

[C++]

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.