Quote:
Originally Posted by JamesTerm
The philosophy we have is to choose readability over performance
|
Yes! To quote Knuth, "premature optimization is the root of all evil".
On 971 and at work, we focus on making sure that our code is readable, testable, and deterministic. Notice that performance isn't a main driver. Every time we've focused on performance too early, we've ended up optimizing the wrong thing. The most noticeable speedups I've seen recently in real-time code were ones where someone reduced the number of context switches or removed some huge copies which were accidentally happening, rather than ones where someone optimized a function call. We recently got a 2x (or more) speedup by switching to polling for log messages rather than waking up for every new log message. We would not have anticipated that in the design phase, and only caught it by profiling and testing.
Quote:
Originally Posted by Peter Johnson
Why the dislike of std::unique_ptr? I can understand not wanting the locking/reference counting overheads of std::shared_ptr, but std::unique_ptr is essentially just a simple wrapper around a pointer to provide scoped destruction (basically a less dangerous version of std::auto_ptr).
|
I agree with Peter here. I've been very impressed by unique_ptr. It has no overhead, or if it does on a poor compiler, isn't worth discussing given it's benefits. Since I started using unique_ptr exclusively, I think I can count the number of memory leaks and use after free bugs that I've seen on one hand.
Quote:
Originally Posted by Peter Johnson
I'm surprised at the recommendation to use std::exception and std::runtime_error. Exception-safe code is very hard to write well, and usually the exception paths are not effectively tested anyway (as they're hard to test). You're almost better off crashing and letting the auto-program-restart functionality get you back up and running.
|
Safe use of exceptions requires use of RAII, which means use of unique_ptr and friends. I've seen a lot of benefit to crashing early rather than trying to recover when architecting the projects that I've lead recently. This is actually one of my complaints with how WPILib handles errors. When was the last time you checked the error object associated with each WPILib object after reading a sensor? As Peter points out, exceptional error paths are rarely well tested. You are likely to hit an obscure bug in your recovery path and crash in a bizarre way from that. At that point, you are way better off crashing early and printing out a nice error at the same time. Of course, every time you hit a crash, you should take the time to understand why it was hit, and fix the bug that it exposed. I've also had similarly good luck with using assert statements to verify assumptions in code for all the same reasons.
I've been following the Google C++ style guide for about 5 years now and been happy with it. We add some small additional constraints when working with real-time code.