![]() |
The OpenRIO C++ Coding Guidelines for FRC
OpenRIO has decided to release some coding standards and guidelines for the C++ programming language, tailored to embedded development on the National Instruments RoboRIO. This short document includes guidelines to ensure good, performant coding practices for FRC.
https://github.com/Open-RIO/C-Coding-Guidelines |
Re: The OpenRIO C++ Coding Guidelines for FRC
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).
While std::map and its kin are very allocation-intensive, it's hard to get more efficient than std::vector when you need a dynamically allocated or resizeable array. It's basically a wrapper around a pointer and a size. 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. |
Re: The OpenRIO C++ Coding Guidelines for FRC
Quote:
We've found that when developing software specifically for embedded systems, especially those on a periodic loop, we want to try and reduce the use of both locking functions and the C++ STL. The main reasoning behind this is that compilers are specifically terrible at optimizing templates and the STL. You'll often find this mindset also carried in Game Development and other applications where performance (and memory usage) is a key factor. Quote:
Quote:
I'll update the document tonight to reflect these clarifications |
Re: The OpenRIO C++ Coding Guidelines for FRC
Given that this a technical discussion of C++, I thought I'd give my thoughts at length.
Quote:
In general, all dynamic memory allocations and resource acquisitions (like a locking a mutex) should be contained within an RAII wrapper to handle cleanup. In modern C++, one typically never needs to use new and delete or C's malloc() and free() directly. Quote:
It is possible to see linear growth in the executable size when instantiating a template with different types because the compiler emits an implementation for each. However, that would also happen if the code was written without templates due to the developer writing two implementations themselves. If the instantiation of two templates is the same, the compiler won't emit a second identical copy (inlining notwithstanding). Quote:
In addition, optimizations can be made to avoid heap allocations. For example, the GCC 5 ABI std::string supports the small string optimization, which allows small character strings to be stored on the stack inside the std::string object. LLVM also has several useful containers, and ntcore and WPILib use some of them on occasion. SmallVector (statically allocated vector), and DenseMap (map which uses contiguous storage) are a few. Quote:
std::array is an iterable replacement for a static C array. Quote:
Regarding rule 6, std::lock_guard is an RAII wrapper for a mutex. |
Re: The OpenRIO C++ Coding Guidelines for FRC
Quote:
" Static function pointers are more efficient both in runtime and by the compiler than calls to a class object " A red flag is raised in my mind when I see the reason argument is for performance gain, which suggest the scope of development here may not apply for FRC programming in general. The philosophy we have is to choose readability over performance as chances are most code is not "inner loops" meaning the iteration count is probably more than 10ms frequency. For FRC we shouldn't need to write inner loops... I've never needed to except for vision... which brings another point... different aspects of code can bring upon different rules depending on what it is doing. Saying that... I say good guidelines here, but don't let them be the be-all end-all. Understand why they exist and feel free to do what feels right for you... as long as the team agrees with your coding standards... it's all good. |
Re: The OpenRIO C++ Coding Guidelines for FRC
Quote:
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:
Quote:
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. |
| All times are GMT -5. The time now is 10:12. |
Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi