6 ms·
C++ Coding Guidelines (2014)
- tilt_error 9y agoI don't think it is possible to state a general list of priorities such like this on all source code and all contexts. What is not apparent here is the context in which these priorities were stated. I could easily argue that maintainability (both reading and writing) is more important than runtime performance in any other given context. What would be interesting is a more elaborate discussion of the priorities based on the context (which is unknown in this case).
- stinos 9y agoVery good point. While all of these guidelines are spot on, I'll also usually favor maintainability/readability (as in proper combination of applying standard Good Practices and design patterns) over anything else, if context allows. Then again, I noticed since C++11 and beyond there is much less of a trade-off between maintainability/readability and runtime performance than there used to be. Might also be compilers getting better, and hardware in general somewhat faster. The latter also being why I start to care less about compile-time performance.
- jandrewrogers 9y agoOne way of looking at the priorities is through the lens of "how difficult will it be to address these topics after the product ships?", with all of the inertia that entails. For example, most runtime performance is fundamentally architectural. Once you ship an architecture it is nearly impossible to change it in practice. You rarely get a second chance to do this correctly. Correctness can be particularly insidious if the code behaves well enough to use. There are many examples of incorrectness that became a "feature" after it shipped because users started exploiting the side-effects of incorrectness in their own applications, making it very difficult or impossible to properly address the underlying broken-ness. A lot of code spaghetti is the product of a janky feature implementation that has some incorrect behavior that needs to be supported indefinitely to keep users happy. (This is what I always fear most when developing software.) Compile times are a partly a side-effect of architecture but in practice you can often make large improvements without materially altering the design of the software. With minimal thoughtfulness in the software design, you can push this off until it really becomes painful without losing the ability to change it. And so on. Readability and writability are among the easiest things to change after the fact.
- makecheck 9y agoNone of these are unique to C++ so I recommend simplifying the title. Even compile time recommendations apply to many languages. Also, it is strange for maintainability to be #4 when correctness is #1 because it is equally important for code to remain correct over time. There is nothing more frustrating than reopening issues over and over because people keep accidentally breaking things in unmaintainable code.
- nickpsecurity 9y ago"Also, it is strange for maintainability to be #4 when correctness is #1 because it is equally important for code to remain correct over time. " Absolutely. This was known far back as Ada which had reduction of errors in maintenance phase as one of its design goals for its syntax and semantics.
- xedrac 9y agoI strongly disagree with the prioritization of compile time and run time performance over maintainability. I can't count the number of times this has bitten me because of some premature optimization someone chose to write. Most of the time the "optimized" code is faster, but it was never a bottleneck to begin with, and is significantly harder to read/modify. Also, if compile time is so important to you, try using Meson as your build system.
- gp7 9y agoCompile time is a huge factor in maintainability!
- jamescostian 9y agoThis doesn't address the argument that sacrificing other factors of maintainability for faster compile times can hurt you in the long run
- michaelvoz 9y agoIt's really not. BUCK and other build systems make compile lightning fast, and when you have a complex multithreaded bug because of sloppy optimization, faster compiles won't help.
- to3m 9y agoThis is exactly the sort of situation where fast compiles often do help, in my view! Debugging is one case where speed of progress can depend on build time, because you need to run the code after each change to see what effect it had and to decide what to do next.
- ardivekar 9y agoOptimised code is occasionally so cryptic that you'll just waste a few hours figuring out what it does, which basically nullifies the effect of faster compile time.
- 9y ago
- pacaro 9y agoI think that expressing these important points as priorities is missing a better way of looking at them. I see them as tensions, the engineer's job and wisdom is in balancing these tensions Except correctness. Code should be correct.
- GnarfGnarf 9y agoExcept in very special cases, I would suggest Maintainability be #2.
- deleted 9y ago[deleted]
- sidlls 9y agoIs compile time a real issue these days? I worked on a code base with thousands of source files and millions (in the 10s [corrected from 100s]) of lines of code 10 years ago and the build process took ~20 minutes. That's a long time, but it was 10 years ago and without a parallel build process. The code leveraged templates and other features of C++ that tend to lengthen compile times, too. Sure, we should strive for minimal compile time (it's expensive idle-time for a developer) but I'm not convinced it's worth allocating developer effort to except in egregious cases. Quality development that doesn't explicitly carve out time to focus on compile time should produce code that compiles in a reasonable time anyway. In general (and for the majority of cases by a significant margin) I agree that maintainability should overrule run time performance. However as always there are tradeoffs to consider. If one is only going to use a program briefly or a small number of times maintainability becomes a lower priority.
- izacus 9y agoYes. For example our project needs about 15-20 mins for a full compile on the most expensive 15" tMBP. (It's about 10 minutes on a desktop machine due to excessive thermal throttling on the laptop but Apple kinda doesn't support those anymore). For an Android build that project needs to build at least two architectures (x86 / armv7) to even function on emulator and target device. CCache, ninja and all other stuff really helps, but we're still talking about minutes of compilation for a C++14 project.
- zeptomu 9y ago> Is compile time a real issue these days? I worked on a code base with thousands of source files and millions (in the 100s) of lines of code 10 years ago and the build process took ~20 minutes. That's a long time, but it was 10 years ago and without a parallel build process. Yes, I think it's still an issue. Let's say your project from 10 years ago took 20m to compile. Using a good build chain one could say, that's possible in 2m today, but this is still a lot of time. Now, if it would take 2s - that would be a real improvement. One should not underestimate the vast benefits of a fast feedback loop.
- sidlls 9y ago
- SimbaOnSteroids 9y agoHow can you lose readibility to something else? Can't you comment what a tricky bit of code does? Full disclaimer, I'm a fairly novice programmer.
- analog31 9y agoI'm hardly a guru, but I think that a tricky code, with an explanation. invites a number of subtle problems. You end up having to prove that the code and its explanation actually agree with one another. For instance your explanation could be crystal clear, but the code could still contain a bug, that's harder to see because it's tricky. Or, someone could update the code and not the explanation.
- khedoros1 9y agoConsider the case when someone is prototyping a hardware device. They might start out with a bunch of separate modules connected by wires, with the benefit that those modules can be reconnected in different ways easily, and the connections are relatively clear. Later, they'll do the work to custom-build a circuit board, chips, and all that to make a marketable product. One problem: The finished product is much harder to modify than the prototype was. We expect software to be more malleable. There are a lot of ways to architect software that will increase efficiency in some way but will make it harder to modify the software in the future (adding new features, closing security holes, etc). On top of that, code that's tightly tied together becomes harder to read. Comments are great, but they've got to be maintained too, except that you don't have customers or compilers/parsers/etc enforcing that. So if a bunch of code is complicated, has a lot of inter-relationships between different pieces, etc, then part of the job is making sure that the comment is up-to-date and still correctly describes the purpose and use of the code. Clever, hard-to-read bits of code should be as small and far apart from each other as possible. Maintainability includes more aspects than just readability.
- SimbaOnSteroids 9y agoThat's a great answer thank you for your response, do you think it would be possible to write a plugin that auto comments code and updates the comments for particularly tricky parts say something that comments [n] then tacks on what n does at the end of the code. Then in the background keep a running list of what got referenced where and updates those references as needed?
- xaedes 9y ago"Make sure that what you assume won't compile actually doesn't compile." How do I do that properly? How do I test for undefined behaviour? I mean when I have code where I know that (ab-)using it in a certain way will trigger undefined behaviour, how do I test that?
- saghm 9y agoIf you want to test that something doesn't compile, you just try to compile it and it either will succeed or fall. UB is a runtime thing, so that's not relevant to this point.
- xaedes 9y agoYou mean including code snippets of not compiling code in the automated(!) tests and compiling them from there? Hm, That makes sense. Anybody know a good framework for this? I can imagine that supporting different compilers output isn't a trivial thing that one should have to rebuild themselves. Btw: The undefined behaviour question was meant to be unrelated to the "not compiling" one.
- saghm 9y agoOffhand, I would just use whatever CI tool you're already using to test various compiler/OS combinations and then just write a bash script to run that compiles a test file (given as an argument) and exits with the opposite exit code that the compiler gives (i.e. 0 for failure, 1 for success).
- gpderetta 9y agoMany test systems allow for expected-fail tests. Also this being c++, of course there are ways to test that an expression does not compile via metaprogramming (i.e. SFINAE).
- saghm 9y agoAlmost forgot to respond to the UB part: you can use clang's UBSAN to help detect when undefined behavior occurs. https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
- azov 9y agoThose priorities are self-contradictory. If you prioritize performance over maintainability, you're sacrificing long-term correctness, which is supposed to be your #1 priority. PS. Also, "C++ Coding Guidelines"? This is neither coding guidelines, nor anything specific to C++.
- partycoder 9y agoThese coding guidelines might be a good idea overall but they do not seem very specific to C++. You could take the same guidelines and apply them to C, Ada, Obj-C, Pascal, etc. If you look for C++ specific guidelines I suggest this: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md https://github.com/isocpp/CppCoreGuidelines/blob/master/CppC... I am saying this since C++ gives you a lot of power, but also a lot of responsibility and room for error making a more specific guide a very desirable thing. Then, you don't use INT_MAX anymore, you use std::numeric_limits<int>::max()