7 ms·
I don't want to turn this into a Go vs. Rust discussion, because the two languages are very different and have very different goals. However, I want to questio
by chimeracoder 13y ago
I don't want to turn this into a Go vs. Rust discussion, because the two languages are very different and have very different goals.
However, I want to question the claim:
> Go is also not particularly friendly to interface to external libraries written in C
which doesn't seem to be explained anywhere in the article, and jars with my understanding.
Go does play very well with C; cgo[0] makes this pretty straightforward.
Maybe there are specific things that the author is trying to do that they found difficult in Cgo, but I would say that Go does play fairly nicely with C; that was a design goal.
Here's a simple example of cgo in action: http://golang.org/doc/articles/c_go_cgo.html http://golang.org/doc/articles/c_go_cgo.html. As you can see, it's relatively straightforward and easy to use.
[0] http://golang.org/cmd/cgo/ http://golang.org/cmd/cgo/
- dignan 13y agoI think it's more of a comparative statement. Interfacing with C in Rust is very simple, as he details in the article.
- derengel 13y agoThe keyword here is "friendly", which cgo really isn't.
- pjmlp 13y agoI never understood why they didn't went the Turbo Pascal/Delphi, Ada, Modula-3, .NET, D way and allowed for proper FFI declarations, instead of forcing a dependency into a C compiler that speaks Go calling conventions.
- acqq 13y agoRust not having the garbage collection as far as I understand can be made to produce routines that are part of C application. As far as I understand, by design Go can't be a "nice" citizen in a C application, the Go routine will bring with itself the whole city it lives in to your flat. So Go applications are something like "compiled, fast Ruby or Python." As far as I understand, Rust should theoretically be a way to write a piece of your application (even mainly C application) in something that gives you a different kind of expressibility. If there's need for that is another question, specifically, I'd like to see some examples that would really impress me. The examples the article author provided give me only the impression "OK it's weirder syntax but it's not so far from what would have to be written in C anyway, so where's the advantage?" What I consider missing for "properly" interfacing with C is for Rust to be able to slurp C headers as they are, without the need for additional "translation" files that are presented in the article. At least the headers without the definitions of the functions. But the declarations of the structures and functions and even basic preprocessing were really, really convenient.
- pcwalton 13y ago> The examples the article author provided give me only the impression "OK it's weirder syntax but it's not so far from what would have to be written in C anyway, so where's the advantage?" Memory safety.
- ZoFreX 13y agoAnd type safety, even when writing macros!
- stonemetal 13y agoAs far as I understand, by design Go can't be a "nice" citizen in a C application, the Go routine will bring with itself the whole city it lives in to your flat. That is correct, but the GP is correct as well. Using C code in Go is easy(just use cgo etc.), vice versa not so much(no such thing as goc etc.).
- Arnor 13y agoAt the bottom of the cgo command documentation [0] is an example of exporting go functions to C. I don't fully understand how those functions work when running in C land (does the GC come with?), but the implementation doesn't look difficult. [0] http://golang.org/cmd/cgo/ http://golang.org/cmd/cgo/
- timtadh 13y agoHow it works (from http://golang.org/src/pkg/runtime/cgocall.c http://golang.org/src/pkg/runtime/cgocall.c ) 36 // The above description skipped over the possibility of the gcc-compiled 37 // function f calling back into Go. If that happens, we continue down 38 // the rabbit hole during the execution of f. 39 // 40 // To make it possible for gcc-compiled C code to call a Go function p.GoF, 41 // cgo writes a gcc-compiled function named GoF (not p.GoF, since gcc doesn't 42 // know about packages). The gcc-compiled C function f calls GoF. 43 // 44 // GoF calls crosscall2(_cgoexp_GoF, frame, framesize). Crosscall2 45 // (in cgo/gcc_$GOARCH.S, a gcc-compiled assembly file) is a two-argument 46 // adapter from the gcc function call ABI to the 6c function call ABI. 47 // It is called from gcc to call 6c functions. In this case it calls 48 // _cgoexp_GoF(frame, framesize), still running on m->g0's stack 49 // and outside the $GOMAXPROCS limit. Thus, this code cannot yet 50 // call arbitrary Go code directly and must be careful not to allocate 51 // memory or use up m->g0's stack. 52 // 53 // _cgoexp_GoF calls runtime.cgocallback(p.GoF, frame, framesize). 54 // (The reason for having _cgoexp_GoF instead of writing a crosscall3 55 // to make this call directly is that _cgoexp_GoF, because it is compiled 56 // with 6c instead of gcc, can refer to dotted names like 57 // runtime.cgocallback and p.GoF.) 58 // 59 // runtime.cgocallback (in asm_$GOARCH.s) switches from m->g0's 60 // stack to the original g (m->curg)'s stack, on which it calls 61 // runtime.cgocallbackg(p.GoF, frame, framesize). 62 // As part of the stack switch, runtime.cgocallback saves the current 63 // SP as m->g0->sched.sp, so that any use of m->g0's stack during the 64 // execution of the callback will be done below the existing stack frames. 65 // Before overwriting m->g0->sched.sp, it pushes the old value on the 66 // m->g0 stack, so that it can be restored later. 67 // 68 // runtime.cgocallbackg (below) is now running on a real goroutine 69 // stack (not an m->g0 stack). First it calls runtime.exitsyscall, which will 70 // block until the $GOMAXPROCS limit allows running this goroutine. 71 // Once exitsyscall has returned, it is safe to do things like call the memory 72 // allocator or invoke the Go callback function p.GoF. runtime.cgocallbackg 73 // first defers a function to unwind m->g0.sched.sp, so that if p.GoF 74 // panics, m->g0.sched.sp will be restored to its old value: the m->g0 stack 75 // and the m->curg stack will be unwound in lock step. 76 // Then it calls p.GoF. Finally it pops but does not execute the deferred 77 // function, calls runtime.entersyscall, and returns to runtime.cgocallback. 78 // 79 // After it regains control, runtime.cgocallback switches back to 80 // m->g0's stack (the pointer is still in m->g0.sched.sp), restores the old 81 // m->g0.sched.sp value from the stack, and returns to _cgoexp_GoF. 82 // 83 // _cgoexp_GoF immediately returns to crosscall2, which restores the 84 // callee-save registers for gcc and returns to GoF, which returns to f.
- kodablah 13y agoWhat about callbacks to/from C code and function pointers? Embedding Go from C? Building shared libs in Go that can be loaded in C?
- jeremyjh 13y agoI believe he is referring to the fact that you cannot write a lib in Go that you link into a C application. Note that this is not just a matter of Go's GC and runtime requirement, but simply the fact that they do not support cdecl / stdcall conventions. There are plenty of garbage collected languages that can be linked into a C program (Lua, Python, even Haskell) - you just have to make extra calls to start-up the runtime.
- noloqy 13y agoThis question was answered by Armin Ronacher three days ago.[0] "Why for instance is it not a good idea to write a library in Go? The reason for this is that Go for needs quite a heavy runtime that does garbage collection and provides a scheduler for it's coroutines." [0] http://lucumr.pocoo.org/2013/8/18/beautiful-native-libraries/#which-language http://lucumr.pocoo.org/2013/8/18/beautiful-native-libraries...