unsafe标準庫包
func Alignof(variable ArbitraryType) uintptr
。 此函數用來取得一個值在記憶體中的位址對齊保證(address alignment guarantee)。 注意,同一個類型的值做為結構體字段和非結構體字段時位址對齊保證可能是不同的。 當然,這和具體編譯器的實作有關。對于目前的标準編譯器(go 1.18),同一個類型的值做為結構體字段和非結構體字段時的位址對齊保證總是相同的。
gccgo
編譯器對這兩種情形是差別對待的。
package main
import (
"fmt"
"unsafe"
)
func main() {
var x struct {
a int64
b bool
c string
}
fmt.Println(unsafe.Alignof(x.a)) //8
fmt.Println(unsafe.Alignof(x.b)) //1
fmt.Println(unsafe.Alignof(x.c)) //8
}
位址對齊保證
為了充分使用
CPU
的指令并獲得最佳性能,為給指定類型的值配置設定的記憶體塊(起始)位址必須是一個整數
N
的倍數,則
N
稱為該類型的值的(記憶體)位址對齊保證,或者簡單的稱為該類型的對齊保證。我們也可以說,這個類型的可尋址值的位址確定是
N
位元組對齊的。
事實上,每種類型擁有兩個對其保證,一種當它作為其他類型
(struct)
的字段,另一種是針對其他情況(如當它作為一個變量的聲明,數組元素的類型等等)。我稱前者為類型的字段對齊保證,而稱後者為類型的一般對齊保證。
對于一種類型,我們可以調用
unsafe.Algnof(t)
去擷取它的一般對齊保證,其中
t
是
T
類型的無字段值,也可以調用
unsafe.Algnof(x.t)
去擷取它字段的對齊保證,其中
x
是一個
struct
的值,同時
a
是類型
T
的字段值。
标準庫
unsafe
中的函數調用總是在編譯期間。