Ranting. My problems with C++
Warning: This is an angy post with my frustrations.
I have been really annoyed by C++ recently. I love C++. It gives me the absolute best performance out of all languages with high level of abstraction. But it has so many problems that makes it borderline unusable sometimes.
C++ gives me 100% control over very fine details on exactlly when and how some low level operation is performed. Unlike GC languages when reading data, with RAII. I can open a file with
std::ifstream, read data then leave. I know RAII will close the file descriptor at the end of the function. Or I can manually scope the object to make it close early. No matter there's some pesky exception. When writing a cache, C++ allocatros allow me to decide a upper bound beforehand. Then react to too much data very rapidly and easily. Intel's TBB provides very good concurrent containers that helps tremendously removing mutexes from my code. Making my code blazingly fast. etc..
For the record. C++ is a very good language.
And there's a ton of problems I've been frustrated with.
- No "it just works" package manager
- Slow compilation without benifit
C++ doesn't have a unversially supported package manager. I understand this stems from the early days of internet. Where sharing source code is not a thing. And it's the distro's responsiablity to package popular libraries. But damn it's 2022. I still have to find some library on GitHub. Make it a submodule. Add CMake support for it. Projects like conan and [vcpkg] is trying to solve them. But they don't "jsut work" like pip (Python) or Go does. Not to mention run the problem of two dependencies depends on different versions of the same library. Then either break ABI or ODR internally.
Without going into detail on how both works. Vcpkg supports installing multiple enviroments. But requires users to add
-DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/install/... for every projects that wants to build against Vcpkg's installed filed. This is definatelly not a solution. Like, hello? No one is going to remember the path of the toolchain when they start a new project. Conan is smaller than vcpkg. Maybe because creating packages for Conan is harder. In any case, unlike Python and Rust devs. C++ developers does not have the habit or publishing their library on package managers.
One solution to all these, and one I use in production is CPM. It is a CMake module that directly downloads repositories as modules and handle CMake for you. It's more like how Rust's cargo works. It populates libraries in the build directory. Then link them when building the project. However, it doesn't solve the ABI/ODR issue. And it does not store the compiled result to be use by multiple projects. Making it unsuited for handling lare dependencies like TensotFlow.
C++ is also notorious for it's long compilation time. C++ grammar is context dependent and ambiguous. Forcing the compiler to spend much time parsing and disambiguating. Furthermore, C++ compilers also spends a lot of time instantiating templates. C++ takes a no magic included approach. Only the most primitive types are defined by the compiler. LIke
int, pointers, etc.. Then everything is defined as an application of the fundimental types. In contrast languages like Java, Go, etc.. has compiler defined array types (let me know if I'm wrong).and so on This is a double deged soard. This makes C++ very flexable while have to parse the standard library everytime it gets included.
The 2 problem should be solved partially by C++20's module feature. Yet the only compiler that fully supports modules is MSVC. Clang is still working on modules support. While GCC seems to have no progress since GCC 11. GCC 12 release notes shows no sign of their module support. (Sigh) This is the chance for C++ to solve their package and compilation issue. But the 2 major open source compilers haven't support the feature 1 year from the next C++ version. Why?
I'm seriously switching my primary language. However I want whatever I choose to have the same performance guarentee C++ have. To be specific
- Gives me complete control over execution and resource allocation
- No virtual machine, must compile to native binary
- Support custom allocators
- Have a package manager
- Easy way to call C function
Which rolls out a huge chunk of mainstream lanuages like C#, Golang, Scala, Haskell, Lisp, etc... Currently I'm looking at Rust, Zig and V.
Rust looks like the most promising option. It guarentees runtime safety at compile time. It is also the most popular language our of the three. However Rust has it's downsides. Namely it does not have dynamic dispatch (i.e. virtual functions). Which makes implementing some stuff more compilcated. Rust is also very strict when compiling. This good but Rust is evolving very fast. Sometimes making code suddenly not compiling after update.
Zig is some really cool shit. Zig supports including C and C++ headers directly in Zig. Making utilizing C code in Zig very easy - I argue this is why C++ is so successful, able to reuse existing code. For example, I can directly invoke
epoll without going through a binding. Zig's build system is also cool. Instead of some config (Rust's cargo) or scripting language (C++'s CMake). Zig build scripts is.. Zig! No more messy configs and no more stupid build scripts.
V is intresting that it compiles down to C. Like how Gnome's Vala does. Howver with emphasis on build speed. Compiling down to C makes V uniquely powerful. Instead generating LLVM IR directly. The Clang C compiler could generate much better LLVM IR from the equlivent C source code. V also supports (almost) stright up including C headers.
Am I going to switch off C++? No, not soon. But you bet I'll be using a new language if the compilers didn't solve the damn issues by C++23 release.
Systems software, HPC, GPGPU and AI. I mostly write stupid C++ code. Sometimes does AI research. Chronic VRChat addict
- marty1885 \at protonmail.com
- Matrix: @clehaxze:matrix.clehaxze.tw
- Jami: a72b62ac04a958ca57739247aa1ed4fe0d11d2df