I recently found my Evernote login and much to my delight it still had a plethora of old notes I had written up about various programming presentations I had watched from conferences such as CPPCon, CPPNow, GDC, etc. Here are a couple of them, I thought maybe it was time to do some sharing!
Writing Great Libraries: 89 Easy Steps – Zach Laine
Writing code that does what you want it to do, correctly and efficiently, is hard. Doing so when you don’t even know yet what you want the code to do yet is quite a bit harder. Yet this is the job of a library writer – the users of a library may have a very different use case from that of the original author. This talk gives lots of practical advice and techniques for accomplishing those goals and more.
- We write libraries for code reuse
- This means the code should be maximally efficient and maximally usable
- Your API must be easy to reason about
- Names are important
- Don’t violate the principle of least surprise
- Make interfaces impossible to use incorrectly
- Avoid aliasing
- Types should be regular, inter-operable with STL, usable in container or sub-objects, constructible anywhere
- Functions should be pure
- Error messages must not impede use of your library
- Don’t slavishly follow these guidelines
Data-oriented Design and C++
90% of problems are outside of compilers scope, the compiler is your friend and can help out in many situations, but cache misses are going to be your performance problems. Usually, the problem is easy to see and easy to improve. Simple stuff like preconditioning data to improve the amount of data you get back from a cache line read. For instance, if you have a class with a velocity and a position you could intelligently pack those variables into a struct that would take advantage of contiguous memory and pack more into a read. A similar issue can come from bad packing of classes and addition of data which could reduce the cache coherence due to type alignment.
Some cool soundbites:
- On multiple inheritance: “… that’s right out, that’s not even a question, that’s just dumb”
- “The purpose of all programs and all parts of programs is to transform data from one form to another”
- “Understand the problem by understanding the data”
- “Everything is a data problem”
- “Solving problems you don’t have creates more problems you definitely do”
- “Reason must prevail”
- “Programmers job is not to write code, it is to solve data transformation problems”
- “Hard problems are hard”
Titus Winters “The Philosophy of Google’s C++ Code
Man, Titus Winters is one switched on dude.
He is one of the Arbiters of Google C++ Style, how awesome is that! This is their guide to try and coherently organise over 4k of developers working on an enormous code base. His approach to maintaining the style guide is to be an engineer, not a zealot. Rules are useful but only when they have reasons which can be understood and argues with. The distilled essence of why they have a style guide is to encourage the good and discourage the bad. It is to try and make it easier to do things the “more correct” way and to make harder to stray into “badness”.
8 Underpinning rules
- Optimize for the reader, not the writer
- Rules should pull their weight – they should have a positive cost-benefit analysis
- Value the standard but don’t idolize it
- Be consistent
- There is a cognitive difference in how experts and novices deal with problems. Experts are better at chunking up problems so they can understand them more quickly. Consistency helps users of all levels understand issues.
- If something unusual is happening leave explicit evidence for the reader (don’t overload if it matters which version of the overloaded function you call!_)
- Avoid constructs which are dangerous or surprising
- Avoid macros
- Global or static variables of complex type which could have destructor issues
- Avoid non-public inheritance
- Always use override and final
- Avoid template meta-programming
- Usually, you shouldn’t need to be using complex language features or doing “clever stuff”. The way to be clever is to make things simple, explicitly broadcast your intentions and make the code so that anyone can follow it through.
- Avoid multiple inheritance (both Titus and Acton have given this a serious kicking, and rightly so!)
- Avoid polluting the global namespace
- Concede to optimisations and practicalities where necessary
Titus Winters – Lessons in Sustainability
Titus Winters is a badass. That is all. Wait, no, that’s not all!
- What is sustainability? First, you need to answer some questions… what is the lifespan? Per project? Monolithic?
- If you do not *have the ability* to fix the issues which arise you will have a problem.
- To be sustainable you need, testing, policies, automation, awareness, practice
- Tests are your first line of defence in enforcing the contracts of your code and the code you depend on.
- The web of trust-by-verification is not a proof that the codebase works.
- Be polite to the people depending on your code by ensuring it works consistently plus keep an eye on the people above you who make mistakes and aren’t to be trusted!
- If it is hard to run your tests no-one will do it.
- Tests do not prove stuff works, they help convince you that you haven’t broken everything though!
- “If you liked it you should have put a test on it”. (Oh my god I love this line).
- No bugs can be marked as FIXED without a test that demonstrates the bug is indeed fixed, it previously failed, it now passes.
- If you didn’t have a test it is not our fault for breaking your code. Grow up.
- Style guides – strongly encourage consistency and safety
- Code review – take it seriously, encourage sane code (number two after testing).
- Software engineering is hard. Software engineering practices help you lean out over the edge. Code review is valuable for the best, you aren’t the best, it is even more useful for you.
- Readability – don’t trust people! They put shit in the wrong place.
TL;DR Watch this talk.