tags:

views:

209

answers:

4

I'm having a look at Go, which looks quite promising. I am trying to figure out how to get the size of a go struct, for example something like

type Coord3d struct {
    X, Y, Z int64
}

Of course I know that it's 24 bytes, but I'd like to know it programmatically..

Do you have any ideas how to do this ?

A: 

See the binary package. Specifically the TotalSize method

marketer
Can you show how to use that the right way ? I tried it several times and didn't really understand how to get the reflection stuff to work..
Homer J. Simpson
+4  A: 
import unsafe "unsafe"

/* Structure describing an inotify event.  */
type INotifyInfo struct {
    Wd     int32  // Watch descriptor
    Mask   uint32 // Watch mask
    Cookie uint32 // Cookie to synchronize two events
    Len    uint32 // Length (including NULs) of name
}

func doSomething() {
    var info INotifyInfo
    const infoSize = unsafe.Sizeof(info)
    ...
}

NOTE: The OP is mistaken. The unsafe.Sizeof does return 24 on the example Coord3d struct. See comment below.

RogerV
The OP specifically said "I tried `unsafe.Sizeof` and it didn't work."
Chris Lutz
if not working with 64 bit ints then should be lodged as a bug. The use of unsafe.Sizeof appears in lots of places in the Go library code and is intended as a cannoical way to do this, especially when interfacing to C libraries and OS API calls. At any rate, it certainly works correctly in code I've written using it.
RogerV
So I checked with the code shown below. The OP was mistaken. The unsafe.Sizeof does correctly return 24 for his example data structure. (My Go compiler was updated first week of January 2010.)package mainimport ( unsafe "unsafe" fmt "fmt")type Coord3d struct { X, Y, Z int64 }func main() { var pt Coord3d; const size = unsafe.Sizeof(pt); fmt.Printf("Size of Coord3d: %d\n",size)}
RogerV
You're right, I was mistaken, I did some experiments with binary.TotalSize and mixed that up with my Sizeof experiments.. Thanks for the demo solution, I couldn't really conclude the right use of it, as I just started to use Go a few days ago, and now trying out how to do the 'usual stuff'..Finding usefull examples isn't that easy yet with Go, although reading the library source turned out to be quite instructive (as with python, for example).
Homer J. Simpson
+1  A: 

binary.TotalSize is also an option, but note there's a slight difference in behavior between that and unsafe.Sizeof: binary.TotalSize includes the size of the contents of slices, while unsafe.Sizeof only returns the size of the top level descriptor. Here's an example of how to use TotalSize.

package main

import (
    "encoding/binary"
    "fmt"
    "reflect"
)

type T struct {
    a uint32
    b int8
}

func main() {
    var t T
    r := reflect.NewValue( t )
    s := binary.TotalSize( r )

    fmt.Printf( "%v\n", s )
}
Evan Shaw
A: 

This is subject to change but last I looked there is an outstanding compiler bug (bug260.go) related to structure alignment. The end result is that packing a structure might not give the expected results. That was for compiler 6g version 5383 release.2010-04-27 release. It may not be affecting your results, but it's something to be aware of.

UPDATE: The only bug left in go test suite is bug260.go, mentioned above, as of release 2010-05-04.

Hotei

Hotei