Hacker News new | ask | show | jobs
by unbendable 2724 days ago
As a embedded systems (C / C++) and a ReactJS developer (both senior, I know weird), I have to admit that the web dev ecosystem is much better to get into. And yes I know the fragmentation is really bad in the JS world. But it is nothing to the cluster fuck that I have seen in the C/C++ world.

And honestly it is not because C / C++ is hard to learn. They just didn't age well. C++ is full of anti patterns, the build system (makefile) is absolutely horrendous (yeah i know about cmake, dont tell me - tell the manufacturer/vendor), the compiler is your worst enemy (gcc errors are useless), testing isn't as widespread as I see it in webdev.

Code Quality is not a concern. I found myself often times looking for the documentation in the source code. And truth be told i rarely find someone advocating against it. IDE support before CLion is laughable compared to IDEA. There was just VS that was nearly as good, but not a option for me as a Linux User.

I had a discussion with someone on a Embedded Meetup and this guy trashed JS because it isn't type safe. I tell you something C/C++ is NOT type safe. You can't trust the type you would expect. NEVER. That is actually a big problem in some use cases.

I am now in a state where I would say that I have a lot of experience in embedded. It took a lot of time and frustration. But I really envy the people that put so much effort into teaching and putting so much content to improve and learn more about webdev. I am aware of the fact that some people are programming trash in JS too. The thing is they didn't need to. It is so easy to find good resources advocating good patterns for programming.

I have read on Rust for embedded and the work that some people put into it gives me hope. I really really wish for C/C++ to vanish in its current state. It is not friendly to newcomers and surely that is not because they re too stupid.

And if I can recommend you some books (for embedded C/C++):

9781788830287 Embedded Systems Architecture (Good Introduction)

9788131521267 Data Structures and Algorithms in C++ (That actually helped me a lot with persisting state in memory, some cool tricks)

EDIT: added some newlines

9 comments

I dunno. I've dabbled a bit in programming (professionally for about 40 years) and I maintain and support the C++ toolchain for a major commercial embedded operating system. I have the opposite experience and opinion about C and C++ development and of the modern framework-based packaged flavour-of-the-month silver bullet solutions marketed as easy and cheap replacements for an educated and skilled workforce that permeate today's web developer market.

So, you know, your experience may vary.

> I maintain and support the C++ toolchain for a major commercial embedded operating system

which one?

In the last 10 years I have never seen a C++ project using Makefiles. Also C and C++ have different set of skills. I probably couldn't contribute to a C project, as I only know the C++ standard library and modern C++'s idioms.

I think you really need to differentiate between C, C++ before C++11 and modern C++ (i.e. C++11/14/17 and newer).

I think it is more of embedded and the desktop C/C++. Makefile is kinda forced through vendors and some "libraries" forcing you to use make as they're exclusively generating (STM) or relying on them (ugfx, touchgfx).

I actually switched some time ago from C to C++ only - when possible. And about the features of modern C++ standards: On embedded you can't use STD or excessively use templates. Some features will crash because of the Memory Protection Unit and are not usable when using the MPU.

But if we are talking about embedded, we shouldn't be making comparisions with ReactJS then. Of course the latter is going to be easier to get into than embedded C++, but not because of JavaScript vs. C++.
I understand where you are coming from. But I don't think that webdev is easier just because it is. Embedded is not the rocket science some people claim it to be.

I believe there is a lot of room where we can improve and lower the barrier for entry. For example better packaging system, better IDE support (CLion is already very good tbf), modernizing vendor api, improve documentation and testing solutions, compiler that actually throw meaningful errors and of course good learning material...

I know it is a lot to ask and I don't want to sound like a ungrateful child. There are a lot of people working their asses off for free and all that. But i think it is not wrong to point some of the problems we have.

Except that cmake is often used to generate makefiles, so now to debug an issue you have to understand both cmake and makefiles! Not much of a progress if you ask me..
Hm ... I've never looked at the Makefile to debug CMake. When did you need to do that?

You can also generate Ninja files btw.

Yes, it just takes a lot of reading and making connections to build a consistent historical picture.

Becomes very easy as soon as you're up to date.

While I agree that some Makefiles are terrible, I disagree that make is absolutely horrendous. It's sort of what you do with it; it's a copy paste garbled mess, of course it'll be terrible but you can make the same argument about maven, sbt and quite a few other build systems.

On another note, besides C legacy (memcpy, printf, malloc, etc.), could you point me towards something that is not type safe in C++ (preferably post C++11)? I find the argument a little bit disingenuous after claiming rust is type safe (you can do the same kind of non type safe magic with the unsafe keyword).

Just as an FYI, “disingenuous” means that you think that the person making the argument actually believes that the argument is false, or is purposefully omitting relevant facts. It is more or less synonymous with “insincere”. I’m assuming that “disingenuous” is not what you meant.
I did mean insincere :). Thanks
To be clear it is inappropriate to call someone insincere when there isn’t good evidence for it. I see people throwing around the word “disingenuous” in Hacker News comments a bit too often. It’s an ad hominem disguised as actual discourse and a rare enough word that some people gloss over it or need to look it up. The accusation detracts from discussion about the topic at hand.

The idea that you were misusing the word was more appealing than the truth that you knew what it meant.

No I never claimed Rust is type safe. I don't know enough about it to make such a claim. I just read some articles and blog post and i really liked some concepts of it.

So I think some people are forgetting that I work and talk only about embedded development C/C++.

Generally what i mean with you can't trust the data is that memory can get corrupted in embedded very easily. There are some mechanisms to prevent it (MPU for example). The other thing that I see often is the usage of opaque pointer by vendors. That is not necessarily a problem with C++ but you will have to use it and deal with it.

But yeah you re right about modern C++ features being more type safe. I would love to use them but the problem is many of those std features are not usable in embedded or are not worth the cost.

> While I agree that some Makefiles are terrible, I disagree that make is absolutely horrendous.

I agree with the parent on this point (although make is not _the_ C/C++ build system) - makefiles are horrible. Make is arcane, full of quirks that bite you as a beginner, and suffers hugely from being not-portable (gnu make is not the same as other flavours, and make on windows is practically non-existent)

> could you point me towards something that is not type safe in C++

Not the parent but [0] is a reasonable example.

[0] https://gcc.godbolt.org/z/csjnM4

I think your example here is pretty disingenuous because you haven't created any types, merely aliases of 'meter' and 'centimeter' that are of type int.

A better example of breaking type safety would be to involve a reinterpret_cast or a C-style cast, or maybe pass something through a void*.

I don't disagree that I haven't created any types, but to someone who doesn't see the declaration of meter or centimeter, it can be difficult to know that. Especially if you combine it with almost always auto.

You can created tagged structs, but you inevitably end up needing to extract the value underneath.

Regarding casts and void pointers, I think they're a slightly less dangerous case. My Spidey senses tingles whenever I need casts - static (or to a certain extent dynamic) casts are normally ok, but a reinterpret cast or a void* parameter is going to warrant a discussion and explanation in a code review.

> I don't disagree that I haven't created any types, but to someone who doesn't see the declaration of meter or centimeter, it can be difficult to know that.

We definitely agree here. Better would be to use a library such as Boost Units, rather than naked aliases.

void* is definitely problematic, and I kill it every chance I get, but it persists in a lot of code due to C libs and unfortunate legacy dependencies.

Sorry I missed this.

> Better would be to use a library such as Boost Units, rather than naked aliases.

Completely agreed.

> void* is definitely problematic, and I kill it every chance I get, but it persists in a lot of code due to C libs and unfortunate legacy dependencies.

I've not seen it (thankfully) in anything other than actual C code or graphics code, but whenever I do see it, I make a mental note of "here be dragons" and make sure to take extra care around there... It's not ideal but it's life..

In a type safe C++ style, 'meters' would be a numeric-like class with explicit casting operators etc.
Would a single member struct work as well? Can C++ optimize that away?
Rust is type-safe (in most senses of the word) if you don't use unsafe. C++ is not.
> I find the argument a little bit disingenuous after claiming rust is type safe (you can do the same kind of non type safe magic with the unsafe keyword).

Rust is probably the most type safe language I’ve ever used, granted it’s not many, but definitely between Java, C, C++, JS, Python, Lisp, etc. If you put Rust in the same category because it has unsafe, you might as well just throw your hands up and say that no language, not a one is typesafe, with the exception of possibly Assembly, which practically treats everything as just a series of bits.

There is a misconception that b/c Rust has unsafe it is proof that it is itself unsafe, but this devalues the entire point of having any form a safety in language.

The language is typesafe, memory safe, and datarace safe, so long as you keep the guardrails on. Sometimes you take the guardrails away for very special reasons, but those are generally rare (unless you’re working with FFI, hardware, or low level concurrency). I have entire codebases of multiple thousands of lines in Rust without the need to use unsafe at all.

>On another note, besides C legacy (memcpy, printf, malloc, etc.), could you point me towards something that is not type safe in C++ (preferably post C++11)?

How about typedef's in general, what problem BOOST_STRONG_TYPEDEF solves (and its limitations)?

Embedded aside, there’s never been a better time to get into C++ programming. The bad old days of the Visual C++ 6 hegemony are over. There is finally good compiler competition. They are no longer stagnant and are supporting more and more features with every release.

Things like smart pointers, move semantics, lambdas, type inference are great additions and can save you from the footguns of the past. And that’s just C++11. The documentation and learning resources on the web have never been better, too.

The problem, as you point out, is on the embedded side, specifically vendor support. There doesn’t seem to be a solution to vendors who don’t give a shit. They scrape together an old build of g++, manage to barely get it to work, and call it a day. There’s probably some “disruption” opportunity here, and someone smarter than me will see it. I think Apple has actually set a great example of how it could/should work. Getting Hello World running on a production, end-user iPhone is 10x easier than getting it working with CrappyChineseVendor’s SuperDeluxe BSP and reference hardware, whose only purpose is to support software development. And Apple’s toolchain is reasonably up to date and gets yearly updates vs the other embedded toolchains which are 5 years old and never get touched post-sale. That should be totally unacceptable but we still hand our money over to these vendors.

> As a embedded systems (C / C++) and a ReactJS developer (both senior, I know weird)

Same here and I thought it were weird. Glad to see someone with the same experience.

You forgot to mention C/C++ package manager. There are approximately 74 different build systems and a patchwork framework of 28 various package managers, most of which only support a certain platform/environment and are useless outside of it.

Yeah that's one of those things I find so attractive about rust. They provide a compiler and a package manager where you can manage dependencies and build setup.

I hope it does not end up like one of those "grass is greener on the other side"-thing :D

> As a embedded systems (C / C++) and a ReactJS developer (both senior, I know weird)

Nothing weird. Someone has to understand the end-to-end embedded-server-webui.

Embedded dev here as well, trying to get into react/webdev. Can you recommend resources you used for React knowledge, particularly in binding it to dynamic information sources, e.g. databases? Documentation and examples seem lacking in that area.
Official React documentation is actually fine. However I have been using it with a backend which provided an API. I have to admit that I rarely see React Applications directly bound to a database (if you meant that, not quite sure). But I would guess that in such a case you're better off with some typed language like Type Script.

To start off I would use the create react app. It sets up a project and all the required settings for babel, linter and all that magic is behind a curtain. Again the documentation is fine for starting. And remember React is just the view library. If you need (global) state management look at redux or mobx, http client axios and read their documentation.

I started 3 years ago with React. Back then i just used the documentation. Now i follow Dan Abramov and other React Maintainer / developer (like Sophie Bits) on twitter and I learn a lot of internal or advanced stuff about react. I definitely would recommend following them.

React is primarily (and almost exclusively) used as a frontend framework. In that context information sources are HTTP apis (and occasionally browser storage, but that deleted at anytime, so pretty much every app also stores data on a server somewhere).

There are lots of ways to connect to these APIs, but a common one with React is to a Redux middleware to do the fetching. Underneath everything, something will be using either the classic "XMLHttpRequest" or the newer "fetch api" to do the actual HTTP requests.

Off-topic: How do you use React with an embedded project? Do you host the web-ui somewhere else and then use data sent from devices to chart results? (most embedded applications I saw were doing auto-adjustment & anykind of output means a tiny LCD display with numbers).

Also, often when C/C++ comes up, more often it is embedded, but when I learned C/C++ it was mostly os/game/dbengine etc.

Embedded sounds interesting but not sure where to start. A few pointers for beginner friendly resources would be appreciated!(will try to get my hands on the books mentioned)

Also, do you think if I start now, Rust is better?

So one thing about react or generally spa's is that you generate artifacts (static files, index.html/js etc.) that you can easily put on anything that serves those files.

That is actually not hard to do on an embedded system. Getting the ETH or WiFi Driver to work is another story. That depends on the vendor and "how many/much batteries are included". Some will make it very easy and offer an fully working API that you can use. But sometimes you need to get deeper for custom solutions and that's when you need to read into the documentation and internal API.

I would start with an Arduino for basic stuff like turning on LEDs. Learn about the PIN Levels or the need of pull down / push up wiring. Try to implement software debounce for input reading. All that basic stuff. Programming is done via their IDE. You get an UART Console (serial) for debugging / logging. I use it to this day for prototyping (last week CAN bus for example to read the OBD interface of my car). There are LOT of resources online for the arduino.

When you re done with it you can look at raspberry pi. There you can use linux (which is very elegant) to do some advanced stuff like networking. You can start with monitoring temperature and printing to the console. There are lot of libraries and documentation for it.

If you are still interested you can go a level deeper. Without an OS or an RTOS (like FreeRTOS). There you are pretty much on your own with a lot of things. I started with an STM32F4. You have an integrated Display on some models. And there is also a lot of tutorials and documentation. The stmcube software helps you setup your pin and board configuration. If you use FreeRTOS: Try playing with tasks (context switching, priorities) or scheduler (cooperative vs preemptive). You can look at the examples provided in the repository (firmware packages) and run them on your board. Play with them, change or modify some parts.

About Rust I didn't try it. But currently i am not sure since the vendor of the board i am currently developing for provides only a API in C. You will either have to write in C or use C++ and write some sort of wrapper (https://www.oracle.com/technetwork/articles/servers-storage-...).

Thanks! Very interesting. I will try to get an Arduino and start from there :)
Out of curiosity, how are you handling embedded programming with makefiles in CLion? Do have cmake run make, use compilation databases, or something else?

I'd like to try CLion with a hobby project and some esp32 modules, but there doesn't seem to be a standard, best practices way to do that.

So my team is using eclipse with autogenerated makefiles. STM used to generate projects only for some WIN32 IDEs and their eclipse. There are 2 hobby projects which I set up with this project: https://github.com/ObKo/stm32-cmake. The genius that set up this github project saved me a lot of work and it worked perfectly with my STM32F746. (Maybe there is a similar project for your board ?)

But for my work project i am using compilation databases, which works great with sources that are included in your makefile. It gets a bit tedious recompiling but there is a way to automate this. Ah one thing that i noticed sources that are not included or libraries with your drivers and middlewares that you link against are not recognized and a warning will appear. Eclipse was a bit smarter as it could resolve those dependencies.

What build system are you currently using ?

So far all I have done is use toy examples I have found on Github. Mostly I've used a text editor without an IDE to make small edits, then make to configure, build and flash. I've also used the Arduino IDE for the very simplest examples and mostly moved on to PlatformIO with VS Code.

My goal is sensors to monitor conditions like soil moisture and temperature, and control pumps on a water catchment system for landscaping, and potentially fire safety control purposes.

If I extend the functionality to fire safety control, that might involve starting a generator, and being able to fallback to LoRaWAN to accept simple commands to run programs and send updates on conditions. During extended power outages in the past I've found that cell towers stop working within a day or so, while only a couple line-of-sight miles away all of the infrastructure is working perfectly fine.

Note that for every thousand square feet of roof area, you can collect about 10,000 gallons per year if you're in most parts of Silicon Valley (16" rain/year), or 20,000 if you're near Santa Rosa (30"). Part of the inspiration for water catchment was the price of water, and the inspiration for automation was seeing photos of swimming pools filled to the brim surrounded by complete fire devastation after the Tubbs fire in Santa Rosa.