profile
engineer . tinkerer . father

Andreas Heimberger

  • home
  • github
  • instagram
  • xing
  • linkedin
Built with Hugo

C++ vs Rust

I always wanted to make a short presentation about C++ with the title: “I identify myself as a C++ programmer, but all the changes drive me crazy”. I guess all of this already started before COVID, spending time looking beyond the horizon, watching all of those online meetups and comparing C++ to different languages especially Rust. So this is my opinionated view of what I have learned so far:

  1. Language Evolution / Learning Curve
    • Back in 2009 I started learning C++ at university. It started with the basics of C++98 (loops, control structures, …), macros, includes, pointers, standard template library, object oriented programming, templates, C++11, and so on. After that it went directly into C++14, 17 and 20 and sooner or later it will go on with C++23. Although it feels good that a language is still developed and improved, it is tough to keep up with all the changes and just by learning the language itself it is not done. The evolution is still ongoing (see: cppfront, carbon language). Additionally you have to learn specific frameworks like Qt. Why those have specific implementations of QVector or QList and then you have to learn about Libraries. Further on there are also all the other non language specific things that you have to learn. How to use build generators like qmake, cmake, bazel and you need to find out how to integrate different libraries. Maybe you also need to adapt a specific style of programming depending on the company you work in e.g. your company has its own style of error handling, or uses the google style.
    • In Rust finding good source to learn the language itself is less complex. All you need is going to the website rust lang. You will find language descriptions and working examples about the language. Integration of libraries and build tools are also very good explained and formatting and styling is also not such a big issue. However, learning the language itself is a steep learning curve.
  2. Library Integration / Build Systems / Tooling
    • C++ has a big variety of how you could handle libraries. Something you could do would be to install a library just to your host environment. In that case you do not have any guarantee that another developer used the same library. Therefore people tend to use either git submodules or cmake to keep there library dependencies. Another approach would be to use conan the package manager. If you go deeper you will also find out, that for some people this would also be a no go, because they don’t like integrating already pre-build dependencies. Another approach would be, that all dependencies might be handled via yocto, but also this is not as easy as said and requires some learnings.
    • With Rust you have a build in package manager, called cargo. It makes it that easy to handle all of your dependencies.
  3. Naming Conventions
    • C++ does not provide one single style for coding, which can make it quite cumbersome. I often had discussions about style of variables, functions and classes. I always stand for consistency, because it makes it easier to read code. If you know it is a member variable (mMember, m_Member, member_, …), or if it is a class (noun, lower case vs capital letter). If you have a deeper look about what is available in the world for naming conventions you find out about different coding style guidelines. If you use it, you will find out, that just following one of those style guidelines feels not intuitive. For example, why should I call the members of a class differently like the members of a struct.
    • In Rust naming conventions are given by the language itself. It might feel a bit weird at the beginning but after a period of time you will get used to style your variables e.g. snake_case.
  4. Testing Frameworks
    • C++ does not provide by default a testing framework. So depending on which project you are working on, you always have to decide what to use. For me it started with Qt Test followed by Google Test. But there exists much more like Catch2, DocTest, …
    • In Rust the testing framework is build in and it is really cool, that you can test next to your implementation within the same file.
  5. Initialization of Variables
    • I guess I will never forget the presentation of Nicolai Josuttis - The Nightmare of initialization in CPP. Watching this presentation just gives you an impression of C++ and what you need to know in the days.
    • Rust just does not have those problems.
  6. Memory Management
    • When you learned C++ like me, you had to think about ownership. Which class might be responsible for managing all the memory on the heap. How to prevent memory leakage and segmentation faults. In the hope to make it easier, C++11 introduced std::auto_ptr, which got quite fast deprecated, because it was unusable with standard containers. Later on you got std::shared_ptr and std::unique_ptr and now there is less thinking about who actually might own the object. But you also got move semantics, which sometimes makes me dizzy.
    • When people talk about Rust they always mention these concepts first: Borrowing / Lifetime and Ownership. So if you read about rust you might already know, that this is one of the biggest improvement over C++.
  7. Templates / Generics
    • Template meta-programming might be something really power-full. I always see its benefit in making something like a std::list or std::vector. But it can also be used in testing to inject a mock . However I never really used it because of its reading complexity.
    • In Rust you have Generics. I think the syntax is much more concise and easier to read.
  8. Standard Library Extensions
    • With all the changes in the C++ language new implementations came up. Not all of those implementations like std::auto_ptr were good. Some of them are however quite an improvement and they seem so simple std::string (numeric conversions, starts_with, ends_with, …), std::optional or with C++23 std::expected. But keeping up with the changes is difficult. Especially if you know that you had to implement them once on your own.
    • Due to the fact that the language is quite new, you do not have to teach yourself again and again. The language itself benefited from concepts of other languages and implemented them already quite well.
  9. Error Handling
    • In terms of error handling you will see everything in C++. Depending on the project you work in, you might have return numbers or enums, std::exceptions, std::optional and sooner or later std::expected. Additionally you have syntactic sugar (noexcept), which still does not make sense for me.
    • In Rust you have a wonderful enum Result, which is either OK or an error.
  10. Code Documentation / Code Formatting
    • In C++ you have too look for the right tools to create documentation from code and to format your code. A free solution for code documentation is doxygen. For code formatting it would be the clang formatter. Due to the fact that you have to set them up explicitly, most companies do not use them.
    • In rust, documentation from code is just build in.
  11. Object Oriented Programming
    • C++ is deeply object oriented. Learning the language you will see data encapsulation, interfaces, object relationships (inheritance / composition / aggregation) and you will for sure learn about many upcoming problems like the diamond problem / forward declaration and other idioms like Pointer of Implementation (aka PImpl).
    • Rust takes a different approach, eschewing traditional OOP features like interfaces and inheritance.

C++ still might be a wonderful language. However due to the fact, that the language itself already exists since 1998 it is quite old and has implementations, which shouldn’t be used anymore. Therefore learning the language is really hard and there are many thoughts about how it should be taught in a modern way e.g. The floor is lava, trying to teach C++ - Patricia Aas. Another problem I often see is, that for various reasons upcoming features are only coming quite slow into some projects. Additionally if you have a big implementation which is only step wise updated to a new language feature it leads to erosion, which might lead to undefined behavior. Finding programmers who share a similar knowledge base is hard and not having good communication and providing information about how something has been implemented, will make it hard for everyone over time.

If I had the choice to start from the beginning I would start with Rust. Rust has clarified so many cumbersome things like style, documentation, formatting. There is less discussion about things that should be clarified from the beginning up. Also language features are thought quite through, and the compiler gives you many useful hints.

A wonderful thing about Rust might be, that you can more focus on how to solve a problem instead of solving the language problem.

Resources

 Personal learnings from the Past   CppFront   Carbon Language   Learn Rust   Naming Conventions   The Nightmare of initialization in CPP   The floor is lava, trying to teach C++