Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Getting C-compatible structs in Go with and for cgo (utcc.utoronto.ca)
39 points by ash on Aug 30, 2015 | hide | past | favorite | 9 comments


This just makes the beauty of Rust so much more clear. Compatible C structs without going through this headache. It also points out another reason why Go is not a "systems" language.


I never understood why they didn't take the FFI route that Delphi, Pascal dialects, Modula-2, Modula-3, .NET, D, Ada, Rust and many other languages do, for describing bindings to other languages.

When I asked about why going cgo instead, the general reaction was "go away we know better", as usual.

EDIT: Typo (way => away)


You could do that in Common Lisp for about 3 decades now. I remember doing this 10 years ago, from the REPL no less.

https://common-lisp.net/project/cffi/manual/html_node/defcst...


From the article:

> (By the way, I do mean 'Sysinfo' here, not 'Cpu_sysinfo'. Cgo is smart enough to take that sort of commonly seen prefix off of struct field names. I don't know what its algorithm is for doing this, but it's at least useful.)

Anyone know why cgo does this? This seems like an anti-feature to me – if I want fields with prefixes that are different from the C ones, at least make that a knob (and preferably one that isn't turned on by default).


It is still useless for me if you have struct with 'packed' attribute ie: http://lxr.free-electrons.com/source/fs/btrfs/ctree.h#L220

  // +build ignore
  package tmp
  /*
  #include <btrfs/ctree.h>
  */
  import "C"
  // 220 struct btrfs_disk_key {
  // 221         __le64 objectid;
  // 222         u8 type;
  // 223         __le64 offset;
  // 224 } __attribute__ ((__packed__));
  type BtrfsDiskKey C.struct_btrfs_disk_key
Output:

  $ go tool cgo -godefs test.go 
  // Created by cgo -godefs - DO NOT EDIT
  // cgo -godefs test.go
  package tmp
  type BtrfsDiskKey struct {
	Objectid	uint64
	Type		uint8
	Pad_cgo_0	[8]byte
  }
After all the experiments I created my own helper[1], which helps map C structure(even packed) to Go structure using reflect package.

[1] https://github.com/plar/btrfs/blob/master/ioctl/mappings.go


> It is still useless for me if you have struct with 'packed' attribute

It's somewhat sad that LuaJIT (effectively a one man project) contains a FFI interface with a hand-crafted lexer and tokenizer that supports the packed attribute correctly.


I wish Go made more of an effort to be more easily C compatible instead of trying to continue breaking away from C.


I think they're just trying to make the best language they can. Surely they shouldn't compromise that for C compatibility?


What could they do to be more C compatible?




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: