Hacker News new | past | comments | ask | show | jobs | submit login
How to learn more as a C++ software engineer? (nullptr.nl)
144 points by ingve on Jan 3, 2019 | hide | past | favorite | 67 comments



C++ is a vast language. If you look at the sheer variety of topics in something like Stroustrups books, there a fair chance any one project doesn't require most of them. Variadic templates, metaprogramming, memory barriers, the specifics of memory layout, public vs private inheritance... How often do you use all of these? Yet if you look at a few projects you'll often come across new things.

It's a good idea to look through one of these books (Stroustrup, Meyers, Alexandrescu, Antony Williams) just to index the topics in your mind.

Then there's the standard library, worth playing with a few data structures to get used to it. Possibly Boost as well though IMO a lot of the good stuff went into the STL.


While I agree that most of your listed examples are likely esoteric enough to escape need in most projects, I am curious to know why public vs private inheritance was amongst them, being that it is a core feature of nearly all object-oriented programming languages.


> I am curious to know why public vs private inheritance was amongst them, being that it is a core feature of nearly all object-oriented programming languages.

Private inheritance is not "a core feature of nearly all object-oriented programming languages". C# doesn't support this, nor does Java. I don't believe Python or Javascript support this in a first-class way either.


I think in Python everything is "public". C# it's been a while, I think you're right though.

If you came from either of these languages and read a c++ file, you'd eventually wonder why there's this extra keyword in the inheritance specifier.


It's just one of those things that turns up in quizzes, what happens to the public/private/protected marked members when you change the inheritance level?

Does it really matter a whole lot? Probably not. Luckily you will find the answer quite quickly if you search for it.


The author mentions a 10-day C++ conference as a turning point for his career. I kind of wish I had that experience because personally I don't seem to get anything out of conferences. I can't think of a single one I would have enjoyed.

Regardless of conference topic, this is how it usually goes: the first talk in the morning is fine, the second one is a mindnumbing one-hour walkthrough of a really complicated way to do something obvious, and by lunchtime I'll rather escape for good than eat lukewarm sandwiches while listening to small talk of how someone's [IoT blockchain startup / enterprise logistics dev team / college course] is amazing because of [conference topic].


I've never even HEARD of a 10-day conference before. Most conferences I've seen are two-days with an optional third, broken up as:

1. Optional "workshop" add-on day, preceding the main conference. Basically a guided tour through writing a Hello World app in Spring Boot, or React, or whatever framework is hot that year.

2. The main conference. Two days of hour-long sessions, with speakers consisting of:

(a) consultants trying to promote their firms,

(b) "evangelists" trying to promote their company's products, or

(c) local devs who don't require travel expenses, and are just presenting a topic to pad their resumes.

Around 90% of the value I've received from technical conferences came from group 2(c), and I'm not sure that was enough to justify the whole.

What the author describes sounds more like "a training class", which is a different animal. Even then, I've never seen a training course longer than 5 days.


I didn't read "I was there for 10 days" to mean a "10-day" conference. CppCon has multi-days classes or workshops that extend the conference. Maybe his employer was good enough to pad the time to cover jetlag. This is something I've seen EU companies do that US companies would never do.

PyCon is the longest conference event that I've encountered, but that involves pre-conference workshops and sprints after the conference. It is great to be able to immerse yourself in the community, but it can be tiring by the end.


Author said he was in Seattle for 10 days, not that the conference was that long. The next sentence (“pre-conference course”) even implies the conference was shorter than that.

The conference I’ve attended most is Siggraph which is one of the larger conferences the ACM has, and it lasts 5 days. There are several well known co-located “pre-conferences”, both of the educational/training variety as well as pure academic.

I get a lot of value out of Siggraph’s content, and almost none from local devs. So, I guess my experience is much more like the article author’s and not much like yours.

Cppcon isn’t really a training class per-se, though, maybe you skimmed and accidentally mixed together what the author said about the conference and the pre-conference class? They’re two different things, FWIW.


I read somewhere (at least 20 years ago) that the best salesmen in the world are constantly going to "how to be a better salesperson" conferences, paying for the thousand dollar fee out of their own pocket. When asked they all said "if I get just one thing that makes me better it will be worth the entire price".

When going to a conference you should be thinking "what is that one thing". There are many different ways to get it: then keynote, the talks, hallway conversations, the vender exhibits, the dinner conversations with strangers. You never know what it will be in advance.


It really depends on the conference.

Ones like Strangeloop out in St. Louis offer an incredible diversity of talks, topics, and forums offered: from language deep dives and workshops to architecture talks to rather arcane talks about modifying an automatic sewing machine to print jpegs onto sweaters and more casual forums on topics like validating resilience and durability guarantees of different datastores.

Ones like Google's series on GCP are exactly as you described though.


Attend CppCon once and it totally changes your mind. Mind blowing number of pure educational talks. There is literally no other conference comparable in terms of technical talks. The rest should be renamed to AdCon.


CppCon, BoostCon, MeetingCpp and others all archive their material on YouTube. I’ve spent countless nights falling asleep on the couch listening to fascinating C++ talks :)


same actually, i always tend to listen to them late at night.


Learn Rust. I'm serious.

The Rust compiler will teach you concepts you need to understand to be an effective C++ developer, like moves versus copies, working with type variables, working with smart pointers, etc.

You could learn these things in C++, but it will be much harder. The Rust compiler error messages are much nicer, and certain features like type variables are at a higher level of integration than equivalent features in C++ like templates. The borrow checker will also teach you how to write hygienic C++ which is something that will take you years to master on your own.

Lastly, Rust's tooling will keep you focused on learning the language rather than fiddling with C++ build systems.


I strongly agree. Think of Rust as a very opinionated and functionally flavoured version of c++.

Also I recommend looking into F#, Haskell and Clojure.


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


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.


This is all great. But the real improvement in C++ skills can only come from real work, solving real problems. No amount of time spent on discord/slack, blogs or conference talks can substitute the real work experience. When you learn something from a blog, book or conference talk, you should go home and apply your new knowledge to the problem at hand, realize the pros and cons, understand the trade-offs. Without this work your knowledge is only skin deep.


Very true, I will add that and more !


My advice would be not to specialize in one language too much. Just don't care about all the clutter that's in C++, you won't need more than a tiny fraction of it ever anyways. A lot of them are shoe-horned concepts brought from other languages. Prefer to learn the concepts in those other languages to get a clear grasp of what their use-cases and benefits are.


Your advice is great, with one caveat: early in your career, people hire you for your potential, so being able to pick things up quickly is the most important skill you need, maybe the only one. Later on, they hire you for your ability to do things. Picking things up quickly is important, but also knowing areas in depth becomes equally important.

So, by all means, people should learn the concepts from other languages. But then, they should also go deep into various areas. Knowing C++ well enough to write portable, efficient, maintainable code, and developing the habits so that's natural, is a good skill to have.


He-he, stop being a `C++` software engineer and become an `anything` software engineer :D


Right?

The moment my programming abilities changed was when I had to write a complex database.

One day I was doing some python job automation and decided I wanted to store the data in a database. I found sqlite existed, now I'm an addict.


Exercises for Programmers by PragProg and try to use Qt with them. Then Effective STL. Then Meyers books. C++ is fragmented between STL/Boost/Qt so you are actually learning three standard libraries.


Isn't this more about the community the author found around a technology they already loved as opposed to any specific knowledge gained about cpp?


Learn Haskell. Seriously. It dramatically improved how I write C++. And I have been writing C++ for 25+ years.


You can always learn more C++. The C++ standard alone is thousands of densely-written pages - and they add to it with every new edition! So, don't worry about ever running out of stuff to learn about.


Agreed. Is the author sure he is asking the right questions? Is learning more C++ The Goal?


It's also worth it to get a copy of the standard(s). The latest standards are pretty expensive (several hundred dollars each), even in PDF form.

ANSI had made the C++11 standard available for $40 several months after it was formally accepted by ISO.

I still use my copy of the C++11 standard time to time. Helpful for explaining why things work in a particular way and for answering "I think I found a compiler/stdlib bug, is my implementation conforming" questions.


My suggestion-

Go home and do a C++ project.

Try turning on stuff with an arduino, then try making it useful.

Or try building a program for yourself.




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

Search: