Does Go has disadvantages compared to C/C++ when using in low-level system and embedded programming?

I’m comming from Python, I’m not experienced yet.

I found Go very good for the huge ecosystem it has, but when I searched for its using in low-level stuff and system programming I came across this comment:

I personally don't recommend it. I did a side project recently for programming a video camera, switched to C++ mid-flight.

The main sticking points:


    ioctl functionality is half-baked. Some kernel functions in Unix-like operating systems will require you to pass a pointer across to ioctl. https://golang.org/x/sys does not support this, so you have to do it using the C ioctl.

    IDE support for cgo is really bad for IntelliJ/Goland. It struggles really hard with typing to the point it almost just gives up.

    You're fighting with the runtime for supremacy over voidptrs, and it's not easy to reason what code is going to pose a memory problem, and what won't.

You're best off just using C++, IMO.

Is the ioctl functionality is half-baked as he says?

will require you to pass a pointer across to ioctl. https://golang.org/x/sys does not support this

/\ This comment is of 3 years ago, but does The Go Programming Language already implemented this feature?

As a disclaimer: I don’t program embedded systems, so take what I say with a grain of salt, and as always: “It depends,” but:

If you’re essentially writing “glue code” between a bunch of C/C++ APIs, then I would not recommend using Go, but if you’re doing any kind of computational work in Python right now, the overhead of going between C/C++ and Go will essentially fade to nothing because of the performance increases you get from running native CPU code instead of interpreted Python bytecode.

I’m not familiar with ioctl, but there are a lot of Ioctl functions in https://pkg.go.dev/golang.org/x/sys/unix, some of which accept pointers as parameters and others that return them, so I’m not sure if that comment is out of date, or perhaps because it’s a golang.org/x/... package outside of the standard library, perhaps the original poster was not aware of it, etc., but I don’t know if that package changes your mind.

Regarding IDE support, I can’t say I’m surprised. After all, cgo is not go. I would hope that you have to write only a minimal amount of cgo code to wrap calls into C/C++ and that the other 99% of your code would be plain ol’ Go. If that’s not the case (like if your project just performs some transformations before passing data to/from C/C++ libraries), then maybe Go isn’t the best choice, at least for that kind of project.

Regarding:

I’m not sure what that means. Perhaps it’s referring to a common “gotcha” when dealing with cgo: That you cannot pass a pointer to C if the pointed-to data itself contains Go pointers:

type OKForCGo struct {
    data0 uint32
    data1 uint32
    data2 uint32
}

x := OKForCGo{}
C.do_something(&x)

type NotOKForCGo struct {
    ptr0 *uint32
    ptr1 *uint32
    ptr2 *uint32
}

y := NotOKForCGo{
    ptr0: new(uint32),
    ptr1: new(uint32),
    ptr2: new(uint32),
}
// not OK, because y.ptr0, .ptr1, and .ptr2 were allocated from Go.
C.do_something_else(&y)

However, if those ptr fields were allocated with C.malloc, then it would be OK because they’re not Go pointers; they would be C pointers, so maybe the original poster is referring to the complexity of knowing if a pointer needs to be C.freed or not because you don’t know if it’s a Go or C pointer?


tl;dr

If you can write most of your code in normal Go (non-cgo) and only need cgo to bridge a gap between your Go code and the OS/some embedded hardware, then Go should be fine.

If your entire program is all about calling C/C++ functions, then Go is probably not worth it.

2 Likes

This is pretty much the heart of the issue. Just adding to this: if I was going to learn a language for systems programming right now, it’d probably be Rust. Maybe Zig if you wanted to be bleeding edge and have a more go-like syntax. Anyway, good luck on your journey and stop back by if you choose to use Go!

1 Like

I found Go amazing when it’s come to cross-compiling, very easy and painless.

Yeah - if you want to know more about why cross-compiling is so painless, check this video at this timestamp:

1 Like

I watched the entire video, thanks.

It would be too bad if after some decades nobody had the idea of creating an almost universal language that generates binaries for several platforms. This language is Go.

PS: I believe that an universal language does not exist.

Depends on what you’re working on (tiny computer vs. microcontroller) when it comes to embedded. If it’s former, everything should operate as the same like a computer so only pick the language that is supported by the hardware of your choice. If something is really odd, then you’re using a very unconventional/purpose-dedicated computing hardware (it’s common in ARM SBC market where sometimes you can get board that can behave likes your router).

If it is the latter, LLVM-based compilers will have trouble because it’s incredibly rare that the chip manufacturers (e.g. Microchip distributes XC compiler) want to support LLVM. I recently kicked Rust off the list partly because of this and mainly because of their overly authoritative governance (too much talking, too busybody, too little productive actions).

I still keep Go because of their algorithms and TinyGo. So far Nim is doing a better job where Nim can transpile into C codes that the proprietary compilers can use. Keep in mind that TinyGo is still work-in-progress but I have good faith in that project.

About the issue with IDE - it’s just a text editor. Swap it out to another one. Codes and IP are not monopolised by Microsoft (VSCode) or IntelliJ or [insert your paid editor here]. Use vim/nano if required.

It’s very immature and childish to claim something is not working because of poor IDE supports. The real work is done by the compiler/interpreter, linters, and code libraries. It’s very strange where you pay so much for a text editor that fails but you’re not making donations to the actual programs that do work.

I’m not being negative. You will be facing a lot of frustrations when coming to low-level development (e.g. thick datasheet, communicating with manufacturer’s customer services, debugging without observable instruments, scheduling, cycle timing synchronisation, …) that you don’t have time dealing with these petty nonsense.

Site-note: but still avoid C-Go whenever possible. CGo was deprecated a long time ago. Go now has GoASM so it should be good for I/O driver level interfacing.

1 Like

I’m not a professional programmer, but an HW expert. For me, the easier to program the more useful it will be. When I discovered TinyGo and Golang I was blown away. Ease of learning and use. Referring to RUST, I didn’t like it at all because it requires more programming knowledge, which is not my main interest.

2 Likes

Fine-grained control: C/C++ offers fine-grained control over memory management and low-level operations, which is crucial in certain low-level system and embedded programming scenarios. Go, on the other hand, abstracts away many low-level details, making it easier to use but potentially sacrificing some fine-grained control.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.