10 Tips for Cleaner C++ 20 Code - David Sackstein - CppCon 2022

preview_player
Показать описание
---

10 Tips for Cleaner C++ 20 Code - David Sackstein - CppCon 2022

The objective of this session is to provide guidelines and tips that will help the audience write readable, testable and extensible code with modern C++.
One of the greatest challenges we face, as programmers, is to make sure that our code can be understood and used by our colleagues - and not only by the compiler.

As the complexity of C++ increases, the compiler is able to deduce and optimize more of our code, but often at the cost of making it more obscure for our colleagues.
Code that is difficult to read is difficult to test, to maintain and to extend.

In the session, I propose to help the audience understand the core problems that we introduce as our programming becomes more advanced, and how we can avoid them.
The main part of the session will discuss some fairly complex and advanced C++ code which is difficult to understand. I will then demonstrate 10 easily applicable tips to make it easier to understand and to test. The benefits will be clearly evident.

There will also be a short discussion with the audience to increase the confidence that the guidelines and the tips are readily applicable in their own diverse projects.
---

David Sackstein

David is an experienced software programmer, consultant and instructor. His passion is to write readable, extensible and testable code and to help others do the same.
David leverages his broad background with a number of programming languages to achieve this goal in C++ too.
He has spoken at ACCU and at CppCon on coroutines and fibers and demonstrated how these tools can help simplify complex programs in C++.
__

#cppcon #programming #cppprogramming
Рекомендации по теме
Комментарии
Автор

dependency inversion is not dependency injection. dependency inversion is about having low level components (UIs, inputs, outputs, databases) depend on high level components (logic, use-cases) in terms of who is deciding on the interface (it should be the high level component that defines the interface)

lefteriseleftheriades
Автор

This was a great talk. I really liked the IoC bit as I was looking for that in the C++ world as a former Java developer.

assonancex
Автор

std::expected is expected in 2023, I want to know how much he giggled writing this title :)
It's nice, we use lots of "Expected" in our code, the Try___ pattern.

Many good aspects but for a 40 minute presentation I think it's a bit too much, could emphasize couple of them instead of trying to tell how to build an application,
I know these aspects so it wasn't so hard for me to follow, others may have issues with it.

TNothingFree
Автор

I'm going to push back a little on the "primitive obsession" smell. Every clean C++ talk seems to push for introducing more and more types, but this increases mental overhead of actually implementing something. I find this kind of advice to have a very strong bias towards maintenance, but in order to maintain something, first one has to actually reach the point when someone can pay for the maintanance, and trust me, there is going to be a lot of code thrown away before that, much more than finds its way to the final product. And if I wrote a struct or whatever is recommended for every number, string etc, I would never get to the point of releasing the product in the first place. Having powerful vocabulary types like int is what enabes rapid prototyping and experimentation, even if their ranges are too wide sometimes. The extra types have their uses, but if all advice a beginner hears is focused on maintenance only, at the expense of experimentation, no new C++ solution will ever be released.

piotrarturklos
Автор

This is pretty decent, but some opinions aren't explained:
- why are comments bad in general? why prefer the additional indirection of declaring small use-one functions?
- why is declaring too much in one file bad? why not group closely related definitions in a single file? what's the advantage pf having the extra indirection of putting related things into separate files?

Swampdragon
Автор

Funny fact: the actual number of tips provided is 11, as shown on the last slide 53:15.

piotrarturklos
Автор

I love the way he presents SOLID as good guidelines but we the caveat of "don't turn this into some kind of fanatical religion" (looking at you development managers)!

edgeeffect
Автор

Would love to use modules, but it's not supported yet by any mayor compiler or build system, apart from some trivial examples.

ChristianBrugger
Автор

Great talk, one comment though is to be very careful with using the "pimpl" idiom. I am currently working on a large codebase for an embedded system which is far from clean code (most is C++03 written as if it were C. It is basically every product developed over 20 years by 200+ engineers baked into a single monolithic application. Someone in the past decided to apply "pimpl" to every class their team wrote which makes navigating the code impossible. Pimpl has its uses but IMHO it should be used sparsely, and only after carefully considering the consequences.

markp
Автор

A good presentation up to the 37 minute mark. After that, it takes a weird turn with few gems. Up to 37 is a good presentation overall, IMO.

colinkennedy
Автор

I'm now more following the John Ousterhouse (TCL/TK creator) way of Software Engineeing. Then from SOLID nothing is left as a guideline except some little I and D. Large closed subsystems that encapsulate a lot of code.

llothar
Автор

32:05 what is the point of throwing if you are then going to wrap the constructor to catch the throw and return it as exceptional? just have the factory method be the one that does the validation.

lefteriseleftheriades
Автор

Lots of useful insights here. Thank you.

andrez
Автор

The example with std::expected and private constructor is unbearably bad. The point of "leave exceptions for exceptional situations" is about making erroneous states unrepresentable. Instead of validating duration and throwing if it is negative in runtime, you should instead define an abstraction of duration that makes invalid duration unrepresentable (should not compile).

SardarNL
Автор

clang-tidy issues lots of false positive for c++20 though

shawnshaw
Автор

Why pass the file name as const string&, if you have the std::filesystem::path object? that´s not clean

PaulMetalhero
Автор

That first bit of library code was so regular I wonder if it was generated by a solver from requirements. Anybody know?

tricky
Автор

I don't feel like IOC containers are so powerful for the example presented. You should already be using interfaces and virtual methods along with composition instead of inheritance, in which case an IOC container is not required to substitute mock objects in tests. Yes a tiny amount of boilerplate can be eliminated with Hypodermic but you still have to code up the registration. Factory methods can be used to contain frequently used "recipes" of registrations and many of these are static anyways. I can see some utility in the container encapsulating all the instances of the related dependencies and maintaining their lifetimes uniformly, when there isn't a more natural way to manage lifetimes. I'm not sure if this is really an interesting design pattern for C++ programmers or if it is just a way to transplant a foreign idiom to C++ instead of using more native idioms.

rickr
Автор

Why create a factory-method only to then throw during construction instead of validating it in the method that was specifically created for validation??? And this still means that you have to do all the error-handling on the callers side. The callers gets an "expected" and has to first validate that he got a movie.

Aside from the obvious glaring problem of defining a maximum allowed duration (that also happens to be way to short for any sane movies) there is something even worse - this example-code does the exact OPPOSITE of what it claims to be doing: it gives a false sense of security cause "invalid" movies are still easily created - only the constructor is checking the duration (with the insane way of throwing an exception) while "Duration" is a simple public member... you can just create a Movie with a duration of 1 second and then set it to say -5 years.
So the object is NOT always valid and if duration is something that must be "valid" then now you have to check it at every point.

ABaumstumpf
Автор

Disappointed he completely disregarded dependency injection with callables instead of interface instances

johanngerell