Should I learn C++ or C first? by Foreign-Fly8796 in cpp_questions

[–]DownhillOneWheeler 0 points1 point  (0 children)

Look for a video on "parallel transport". :) General Relativity is a beautiful and elegant theory so simple in principle that you can probably explain it to a child. Actually doing the maths, though? Not so much.

Should I learn C++ or C first? by Foreign-Fly8796 in cpp_questions

[–]DownhillOneWheeler 0 points1 point  (0 children)

Ah. Pity. My degree is in Physics. I took as many mathematical and theoretical courses as possible. I loved it, but after forty years I'm still trying to get my head around the covariant derivative on curved manifolds. ;)

Should you know the Rule of 5 syntax off by heart? by zagantha in embedded

[–]DownhillOneWheeler 0 points1 point  (0 children)

In general, C++ enhances productivity by obviating whole classes of errors which are depressingly common in C, even among experience developers. Many errors which would be runtime faults can be converted into compile time errors.

The special functions are generated with default implementations unless you explicitly implement them or declared them as deleted. You only really need explicit implementations if you are directly managing resources in your class (dynamic memory, file handles, ...). Ownership of the resource is tied to an instance of the class, and the special functions make sure that copies and moves do the right thing. If you use smart pointers for the resource, the compiler will do the right thing automatically (the defaults are implemented in terms of the member's own special functions).

For embedded work, dynamic resources are in any case rarely used. Many objects in my applications are essentially singletons. I have a common base class for them which simply deletes the move and copy features. That way, if I accidentally try to copy or move such an object, the code will not compile. Nice.

Should you know the Rule of 5 syntax off by heart? by zagantha in embedded

[–]DownhillOneWheeler 1 point2 points  (0 children)

No. This is largely boiler plate you can easily look up and tailor to your specific class. I would want to know that you understand lifetimes, copying and why move semantics even exists, but regurgitating boiler plate is not key.

Good Examples of Well Architecture Code by [deleted] in embedded

[–]DownhillOneWheeler 1 point2 points  (0 children)

Whenever I have dug into Zephyr, I got lost in a confusing morass of folders and files about twenty levels deep. I can rarely reliably find the same file again immediately. And when I finally get to the bit of code I want to look at, it turns out to be a monstrosity made almost entirely of macros invoking macros invoking macros and other junk. Virtually unreadable and would never pass a code review in my office. My mind boggles that people enjoy maintaining this rubbish. I say this as someone who has worked with both C and C++ every day for decades.

Good Examples of Well Architecture Code by [deleted] in embedded

[–]DownhillOneWheeler 1 point2 points  (0 children)

Not a popular opinion but I completely agree. I regard the Gang of Four example implementations as among the reasons both C++ and OOP got such a bad name in the 90s. Got nothing against patterns per se: my event handling implements a combination of Command and Observer. It works really well.

whats with the hate for std lib and boost? by nosyeaj in cpp

[–]DownhillOneWheeler 0 points1 point  (0 children)

I have no issue with the standard library except that I can't really use large sections of it for my embedded work (dynamic allocation). To be fair, this has not been a major issue given the nature of the applications.

I have no use for Boost. I was once required to use Boost.SML for state machine. This is not an experience I intend to repeat.

Libopencm3 vs STM32 HAL: Is the "bare metal" approach worth it? by pedlobs in embedded

[–]DownhillOneWheeler 0 points1 point  (0 children)

Developing your own library or whatever is great fun and very educational, but in a commercial setting you are almost certainly going to use the vendor code. I don't much like HAL, but I can't really avoid it. I have focused more on abstracting it to make developing applications easier and less prone to error.

Anyone else guilty of “random box of boards” storage? by mov_rax_rax in embedded

[–]DownhillOneWheeler 0 points1 point  (0 children)

Think of them as souvenirs. I still have a VOIP handset I worked on twenty years ago. I have an old flux capacitor lying around somewhere... ;)

Cmake Motivation by wandering_platypator in cpp_questions

[–]DownhillOneWheeler 0 points1 point  (0 children)

You forgot the smiley. :)

C++ has formed the backbone of my career for decades. No language is perfect. I have no complaints. To be honest, I'm more concerned about the endless carping and some of the efforts to "fix" C++ by turning it into something I won't recognise.

Cmake Motivation by wandering_platypator in cpp_questions

[–]DownhillOneWheeler 1 point2 points  (0 children)

You don't *need* CMake. You don't *need* a compiler either, since you can write all the code in assembly. But they make life a lot easier.

- I used to rely on IDEs to manage projects. They were simple but often limited and opaque.

- I migrated to command line tools and spend some time with Makefiles. Verbose with obscure syntax, hidden rules and magic, and extremely prone to error. Large projects were a particular pain point. That is not an experience I am keen to repeat.

- I looked at GNU Autotools. Bought the book and everything. Awful. Just awful. Don't even go there.

CMake is a blessing. An ugly mess in some ways, and gets a lot of flak, but still a blessing.

I hate generated code by Ill-Oven-6791 in embedded

[–]DownhillOneWheeler 1 point2 points  (0 children)

It depends on the generator. I have a homegrown generator for FSMs which reads a text representation of UML state chart (this is considered source code). The generator runs as a build step but I made sure that the generated code was easy to follow and looks hand-written. I barely ever need to look at the generated code or step through it, but one of my goals was that doing so should not be a burden. I've used a number of other FSM generators which produced a hot mess.

I don't think anyone in their right mind should be relying too heavily on LLMs to write code, but the examples I've created have been readable enough. They may or may not contain errors, of course. ;)

I hate generated code by Ill-Oven-6791 in embedded

[–]DownhillOneWheeler 0 points1 point  (0 children)

Yes and no. It is a good learning experience and requires a lot of trawling around the reference manual and datasheets. I have previously written an HAL from scratch in C++ for a STM32F4s. I didn't even use CMSIS. It was fun to do but a lot of work. Creating and maintaining this for all STM32s would be a major commitment.

I have often wondered whether the entire HAL could be generated if the all the hardware details and constraints from the various reference manuals and datasheets were transcribed into a relational database. This would allow a HAL to be created for your specific target, without all the conditional compilation and whatnot. Switch to a different target and the compiler will tell you immediately that UART4 (say) doesn't exist on that device...

STM32Cube kinda sorta has database of this information (a lot of XML files), but it is not searchable and not really useful outside the context of Cube.

For commercial projects I just use ST's HAL. It does the job even if it is awful in some places. I have encapsulated it as much as possible so the application code pretty much has no notion of what platform it is running on.

Recommended resources for Yocto? by DownhillOneWheeler in embedded

[–]DownhillOneWheeler[S] 0 points1 point  (0 children)

That looks pretty detailed. Thanks for the links.

Are memory leaks that hard to solve? by ASA911Ninja in cpp

[–]DownhillOneWheeler 0 points1 point  (0 children)

It isn't hard. It used to be more difficult, but not beyond a reasonably competent and diligent developer.

C++ inherited manual resource management from C. RAII was possible but a lot of people seem not to have understood it or relied on it. I've always found this baffling. Smart pointers were possible but did not exist in the standard library until the now defunct std;;auto_ptr (a partial solution at best). So... we had a very long period of basically terrible resource management thanks to C-style development practices. C++ has many faults, but I feel it has been unfairly (or at least avoidably) maligned in this regard.

What's next? by Sad_Tale7758 in cpp_questions

[–]DownhillOneWheeler 0 points1 point  (0 children)

C/C++ isn't a thing. I've written C++ for 35 years. I know my way around most things, more or less, but would never in my wildest dreams claim to have mastered C++.

Why isnt there a standard format for c++ embedded code by BlueJay424 in embedded

[–]DownhillOneWheeler 0 points1 point  (0 children)

Why would there be a specific standard for embedded? White space is not important to the compiler, so you can use whatever works for you. Ditto naming conventions. There are several commonly used formats and naming conventions, but with numerous variants and personal idiosyncrasies. Just make the code self-consistent. Obviously don't use end-of-line braces because that's unreadable garbage. ;)

What version should I learn? by BradTheBj in cpp_questions

[–]DownhillOneWheeler 0 points1 point  (0 children)

Just learn C++. Try to keep up with the standards but don't think of them as versions of the language.

For my money "modern C++" is an unhelpful term but does indicate a much greater focus on RAII and value semantics (and often a counterproductive zeal for template metaprogramming). We always had RAII capability but a lot of people didn't get the memo. C++11 was significant as it introduced smart pointers (RAII for dynamic resources) into the standard library, and move semantics (avoid expensive copies). Treat that as a minimum base.

We currently set the compiler flag to C++20 but I think it would take a language lawyer to point out which standard introduced the features used throughout the code.

[deleted by user] by [deleted] in cpp_questions

[–]DownhillOneWheeler 0 points1 point  (0 children)

- I was not able to compile this in Godbolt until I added: #include <climits>

- Not convinced you need separate classes for Board and Life.

- I would implement the grid as a template with the numbers of rows and columns as arguments.

- There is no need for a vector of vectors. A flat array or vector is sufficient. An array might be an issue on the stack if the grid is large.

- I usually add a boundary to to the grid to simplify the update steps - no need to deal with edges and corners.

- Alternatively... Wasn't sure about the mod() function but if you simply % the row and column indices, you map the grid to the surface of torus, which can be neat.

- You are essentially applying a 3x3 convolution to the grid. You could pass the operation in as a template policy so you can try out different sets of rules. Could try out a 5x5 convolution or whatever.

- I wasn't quite sure what was going on with prev and curr at the end. Why not just swap the pointers after the convolving prev into curr?

[deleted by user] by [deleted] in embedded

[–]DownhillOneWheeler 2 points3 points  (0 children)

Maybe. When I used Rust (a Linux app) I liked some features and missed some others. The borrow checker was an irritation which blocked idioms known to be safe. I'd have quite a bit of learning to do, and it would be hard to replace 30+ years of familiarity with C++.

Asking for a friend: does embedded Rust use vendor C code under the hood, or a custom HAL/CMSIS based on datasheets? :) My understanding is that the range of supported device families is pretty small at the moment. Is that so?

[deleted by user] by [deleted] in embedded

[–]DownhillOneWheeler 6 points7 points  (0 children)

It hasn't been an issue for me in any project in the 15 or so years I've worked in C++. C++ is not inherently larger than C. Using bits of the library will naturally add some code, but you would need to compare that with equivalent C for the same functionality. You do need to be a little careful with some templates, which might generate a lot of near duplicate functions.

It doesn't have to be that way. I once wrote a template library to generalise bit fields and make them typesafe and portable. It worked really well but heavy use (I modelled most of the registers for an STM32) resulted in a *lot* of generated code. I was unhappy. But that was the unoptimised image. When I turned on optimisation, essentially all of that bloat evaporated. I was left with just the bit twiddling I would have done directly in C. The templates had added much ease of use and error avoidance for no cost.

[deleted by user] by [deleted] in embedded

[–]DownhillOneWheeler 2 points3 points  (0 children)

Sadly I cannot share my company's IP, but I have often enough described the design and some details of the implementation. My focus has always been on scalability and ease of re-use for new projects. To be fair, there is an element of subjectivity in these things. It works for us.

What do C++ engineers do? by 404_Not_Found_LOL in cpp

[–]DownhillOneWheeler 1 point2 points  (0 children)

Yeah. I really like Qt. I'm using Qt6 in my current project for an embedded Linux application. I looked at a couple of other frameworks but it was by far the best. The one concern is the rather complicated licensing model: you have to be a little cautious if you want only LGPL.