CPP, C++ Pain Points
The results of the 2023 Annual C++ Developer Survey "Lite" are out, providing valuable insights into the experiences of C++ developers. One of the survey’s takeaways is the identification of some pain points faced by C++ developers.
Let’s look at the question that addressed the topic of pain points.
Which of these do you find frustrating about C++ development
There were 16 questions in that category. Respondents were asked to rate the severity of each issue on a scale of major pain point, minor pain point, or not a significant issue for me.
The top 3 reported pain points are:
Managing libraries my application depends on
Setting up a continuous integration pipeline from scratch (automated builds, tests, …)
Just to mention, number 4 on the list is Managing CMake projects which I see as related to the first ones.
It is interesting that for C++, notoriously known - and criticized by its users - as a complex and large language, the major issues seem to be infrastructure ones.
There can be reasons for that. One is, for sure, the audience of the survey. More than 50% have more than 10 years of experience with C++, and in sum, nearly more than 80% have more than 5 years of experience. So for this audience, I guess, the language itself is not the major pain point anymore since users learned to deal with it. But the infrastructure around it is a challenge.
Let’s look at the top 3 reported pain points in reverse order.
Nr 3: Setting up a continuous integration pipeline from scratch (automated builds, tests, …)
From about 1700 results, 31.35% considered this as major pain, 40.85% as minor pain, and 27.80% as not a significant issue.
I am surprised that this topic is rated that high as a pain point.
For personal projects, GitHub or GitLab CI has brought enormous help in the last few years. If there is no problem with dependencies, which is handled in the following topics, setting up a CI/CD pipeline is a matter of minutes once you manage the basics. There is some learning curve, but the basics are relatively easy to learn. It is doable in an afternoon or two.
And for professional projects, I expect a dedicated team or person to do the CI/CD setup. I agree that dealing with that CI/CD situation, or team, can be a pain point, and often is. But that is maybe not what the question is about?
Nr 2: Build times
From about 1700 results, 43.34% considered this as major pain, 37.56% as minor pain, and 19.10% as not a significant issue.
Build times can indeed be an issue. There are multiple reasons. The project may be big. The lack of dependency management may lead to a huge mono repo, and caching does not work properly. Or purely configured virus scanners slow down build processes.
C++ tries to address some aspects of the problem with the instruction of modules in C++20. And some tools can help to speed up the build process, like ccache or distcc. But they also put you quickly in need of a dedicated team or person to manage them. Incremental builds solve for developers a lot, so the problem is not that bad. Except you work on the one header everyone uses 😉.
But for deliveries you want or must build from scratch, preparing third-party libraries, or building your Yocto base system, build times can be a real issue. And I guess these are the topics where the feedback comes from.
Nr 1: Managing libraries my application depends on
From about 1700 results, 47.37% considered this as major pain, 35.09% as minor pain, and 17.54% as not a significant issue.
Nearly 50% of the respondents consider managing dependencies as a major pain point. That is a lot.
Managing dependencies is indeed a problem. Not everyone is Google who can say, let’s don’t use OpenSSL and develop our own crypto library. Most projects will have to take what is available.
The problem starts already with build systems. There are no standard build systems for C and C++ libraries. Chances are, if you use 5 dependencies, you have to deal with 3 different build systems.
Once you have built the dependencies, you need to figure out how to make them available to the projects you want to use them. That works differently over platforms, target systems, and of course, for the build system used.
If you work on Windows and deliver for Windows, or on Linux and deliver for Linux, or an embedded Linux, you might be lucky and find a solution that works for you. That might be the case for people who consider the topic as no issue, or a minor pain.
If you have to do that for multiple platforms, you have a decent sized problem. And that does not even mention the problem of keeping track of security issues in your dependencies, and reacting to them.
And it continues, different compiler settings, debug and release builds, sanitizer builds, … all that needs to be managed.
Companies often do not have that on the radar. They want to see features realized, not spending time on managing dependencies. That features can often not come to life without managing dependencies is something that needs to be learned.
There are C++ dependency managers that claim to have solved the problem. And for some kinds of projects, they might be a solution. But they are not a silver bullet. They often add another layer of complexity and fall short in advanced scenarios where you build for multiple platforms with multiple compilers in multiple configurations and need to deliver to multiple teams so they can work.
Vcpkg and Conan work nicely in scenarios but have their limits. Tools like spack are not platform independent. Other approaches like CPM or FetchContent transform projects into mono repos, introducing other problems. And we have build system like meson or xmake, which come with their own dependency management solutions. On top of that, every dependency you use might have its own idea of how it deals with its dependencies and how it wants to get built. And once you solved all of that, if you need to deliver to multiple teams with different requirements, tools, and cultures, you enter another problem domain.
In short, managing dependencies has the potential to be a mess. And for some projects, it can quickly become an expensive mess.
So yes, I see managing dependencies in C++ as a major pain point. That was my answer to the survey. And it seems I am not alone in that point of view.
Each of the topics could be an extra blog post, essay or even a book. A lot could be said, but the gist is, there is a C++ infrastructure problem.
C++, as it is today, may not be able to solve that problem. At least not in the context where the C++ standard gets developer, ISO/JTC1/SC22/WG21. I might be wrong about that, but I think if we want to solve the problem in the context of a standard, we might have to look at ISO/JTC1/SC7 and it’s working groups, or something similar. Maybe a liaison with ISO/JTC1/SC7/WG4, Tools and environment, could be realized. I am not optimistic that this will happen, but who knows.
I do not think this topic can be solved outside of a standard. Solutions outside of a standard brought us to the point where we are today. A major pain point.
Do other languages have the same issues?
It depends. Natively compiled languages have similar problems. Rust shares the compile time issue. Golang compiles amazingly fast. Both claim to have addressed the dependency management problem, but there are still limitations and issues with their solutions. Both have package manager systems that fetch source code from Git repositories and build the dependencies on the developer’s machine. And both still depend often on existing C libraries that they expect on the system. Pre-compiled, and shipped by another package manager.
There are ways to archive the same result with C++, either by using one of the CMake package managers, like CPM, or a build system like Bazel, that can fetch dependencies from Git repositories and build them on the fly.
But that approach has limits to scale. Less of a problem for Golang, with its super fast compile speed, but certainly a problem for Rust and C++. That can only be solved by effective caching strategies, which is not easy. But that would be a topic for another post.