C++ Core Guidelines

I end up writing C++ for $DAYJOB every 2-3 years, and it looks like I'll be doing so again soon. Every time I return to the language I look to see what has changed, and this time it's the turn of the Core Guidelines (a surprisingly impressive coding standard). Aside from my opinion on the current state of the C++ language, I find its evolution over the decades fascinating. Idiomatic C++ now is a totally different language to what it used to be. Unfortunately, the old idioms still compile so people use them, but that doesn't need to be the case any more.

A while ago, I studied the SaferCPlusPlus library. It was very impressive, but there's always some risk in adopting a 3rd-party library (i.e. you may end up responsible for maintenance yourself). Since I looked last, the Core Guidelines checkers and support library has made enough progress to be useful. I suspect this may only guard against 80% of the memory safety bugs SaferCPlusPlus would, but on the other hand you're much closer to the mainstream.

SaferCPlusPlus

C++ Core Guidelines

That's enough theory, how do you actually do this in practice?

Static Checking

A central tool is a checker for the core guidelines. This is built into MS's compiler, and the "clang-tidy" program in llvm (which I used).

Annoyingly, MacOS doesn't ship clang-tidy. But if you install the "llvm" package in Homebrew, it'll be in $(brew --prefix llvm)/bin (which you should add to your $PATH). Ubuntu Linux has a clang-tidy package too.

Then you can add a make rule like this

.PHONY: tidy
tidy:
	clang-tidy --checks=cppcoreguidelines-* foo.cpp -- -I/usr/include/c++/11 -I/usr/include/x86_64-linux-gnu/c++/11 -std=c++17 -I/opt/homebrew/include

Feel free to adjust the "-I" options as required.

Library Support

When your run the above checker, you'll get lots of draconian warnings. Some of these have to be resolved by following the Core Guidelines above, especially the new pointer ownership tracking. This feature (and other useful ones) are provided by the "cpp-gsl" package in Homebrew and the "libmsgsl-dev" package in Ubuntu Linux.

Then you need to change your code, things like:

Conclusion

I used to like C#, but I now think it consumes too much energy--I'd rather run a system on one large VM with SQLite than wrestle with multiple servers or k8s. For native code, the closest you can convice conservative employers/customers to go with may be C++ with the Core Guidelines (e.g. ISO standard). Safety is probably not as complete as D/Go/Rust/etc., but it's much better than I expected and there is a definite niche.

Back to my gemlog