cgo does not support union ?

1,446 views
Skip to first unread message

Allan Xu

unread,
Sep 15, 2013, 3:11:23 AM9/15/13
to golan...@googlegroups.com
package main

/*
typedef union _B{
        int b;
        int c;
}B;
typedef struct _A{
        int a;
        B b;
}A;

*/
import "C"

func main() {
        var a C.A
        a.a = 0
        a.b.b = 0
}


a.b.b will not be found in struct A while building.
It works OK in c compiler like gcc.

Carlos Castillo

unread,
Sep 15, 2013, 8:40:35 AM9/15/13
to golan...@googlegroups.com
CGO converts the go-code you wrote (using the C import), into valid go function calls, pointers, structs, and variables. It also provides C-code that converts between go's runtime conventions and C's. For every value, pointer, and struct, an equivalent go type is made, so the memory is used directly. The important thing to take out of this is that the go code it produces is in no way special compared to any you'd write.

Go doesn't have unions, and go structs can't have fields that alias other fields, so C unions can not be represented by an "equivalent" type. They are instead treated as a block of memory in the form of a byte array.

If you run "go tool cgo main.go" you will see in _obj/_cgo_gotypes.go that C.B is defined as "type _Ctype_union__B [4]byte".

You must use a unsafe.Pointer cast to read/write the appropriate type. eg: 
ptr := (*int32)(unsafe.Pointer(&a.b[0]))
*ptr = 42

Allan Xu

unread,
Sep 15, 2013, 10:45:10 PM9/15/13
to golan...@googlegroups.com
thank you Carlos:)
Reply all
Reply to author
Forward
0 new messages