Sailing with C++

The tempest rages in the night. The deafening rain pelts the deck and the waves relentlessly rock the frigate. A dense fog starts rolling in. It is approaching rather quickly and I start to get worried. But then… there is a whisper heard — a perilous portent of carnage. I’ve heard stories like this before. Ships run into an abnormal fog and the crew hears that hysteria-inducing silent scream. Nary a single vessel survives. This isn’t fog. Nay. This is a cloud of a million bugs. I start running around and panicking. What are we going to do? The swarm is now upon us. Bits of remains are flying left and right. The sails are hanging in tatters. The situation is hopeless! Bjarne help us all! We’re never going to survive! I’m screaming, “Abandon ship! Abandon ship!”

I started awake in a cold sweat. Not again, I thought. I shook my head. What have I gotten myself into?


The time had come to learn the ropes of C++.

Of course, I had heard many stories about its wiliness and its devilry but it was time to stop being a rapscallion and take on the maelstrom. What can I say? Perhaps I was craving more control. Perhaps I had had enough of being a landlubber and wanted the freedom of the sea.

Photo by David Dibert on Unsplash

I had captained some C before — sometimes required by schoolwork, other times for side projects. On the one hand, I was expecting to see similar hurdles and subtle gotchas compounded by the bulk and added complexity of C++ over C. On the other hand, I thought surely… surely it can’t be that bad since C is not nearly insurmountable. And while C++ may be more complex, is it necessarily more complicated? I was expecting fair winds as I left port. Because C++ is an improvement over C… right? So I was optimistic.

At first plunge, the experience is overwhelming. Learning the ropes is an effort and it takes a while for one to feel seaworthy. There is so much strange syntax, many subtly different concepts and idiosyncrasies to learn, and many new libraries to deal with. So C++ is kind of the opposite of a friendly sailboat language. It’s more akin to a dreadnought flying the Jolly Roger. One well known thing about C++ is its bevy of keywords. Two of my favorites — based on zero knowledge of their meaning — are reinterpret_cast and friend. This already made my eyes water. But perhaps more surprising were the keyword alternatives to certain operators: and, or, xor, etc. They really aren’t necessary.

Here are all 113 keywords/reserved words in C++ (this includes newest additions as well as pre-processor directives):

alignas, alignof, and, and_eq, asm, atomic_cancel, atomic_commit, atomic_noexcept, auto, bitand, bitor, bool, break, case, catch, char, char16_t, char32_t, class, co_await, co_return, co_yield, compl, concept, const, const_cast, constexpr, continue, decltype, default, delete, do, double, dynamic_cast, else, enum, explicit, export, extern, false, final, float, for, friend, goto, if, import, inline, int, long, module, mutable, namespace, new, noexcept, not, not_eq, nullptr, operator, or, or_eq, override, private, protected, public, register, reinterpret_cast, requires, return, short, signed, sizeof, static, static_assert, static_cast, struct, switch, synchronized, template, this, thread_local, throw, transaction_safe, transaction_safe_dynamic, true, try, typedef, typeid, typename, union, unsigned, using, virtual, void, volatile, wchar_t, while, xor, xor_eq, #define, #defined, #elif, #else, #endif, #error, #if, #ifdef, #ifndef, #include, #line, #pragma, #undef, _Pragma

By comparison, JavaScript has 60 reserved words, Java and Rust have only 53 reserved words, C and Python both have 33 reserved words, and Smalltalk-80 only has 6 reserved words. (Swift has over 90, but we don’t talk about Swift.)

Despite being overwhelmed by everything, I thought the best way to quickly learn would be to set sail immediately and write a C++ library. Of course, that was before I learned this was not possible! By far the most aggravating characteristic of the language is that any caller must know the exact size of a class they are instantiating. In and of itself, this isn’t necessarily a problem and is in some ways logical. However, the size of a class includes its private fields as well. Distributing a C++ static library involves distributing with it a header file that acts as the “public API” of the library, containing its public functions and classes. The issue is, any public class must also have its private fields declared in the header file to be correct and usable.

This is clearly a personal slight against my ethos. I cannot live with anything explicitly private being revealed in any way. It feels like opening a porthole on a submarine. Fortunately, me hearties have come up with a bittersweet work-around: the “PIMPL” idiom. What a hoot! “Private implementation”? Sounds like what I want!

Instead of defining private fields in a public class, declare them in a separate class (the PIMPL class). Then, leave a single pointer in the public class pointing to the private one. Well this is just outrageous. I mean, sure. It solves the issue. But what a hassle! Not to mention it can also cause issues when dealing with class templates. Might as well be called the “porthole implementation”.

Unfortunately for C++ developers, the way the language works prevents solving this issue easily. Partial class-prototypes seem to be out of the question. Perhaps an extra compilation step to automatically apply something akin to the PIMPL idiom might be feasible but would be far from trivial when dealing with complex templated structures. I’m crossing my fingers for a C++ version that addresses this somehow.

In the meantime, I’m hoping I don’t get scurvy from the lack of satisfaction.

Once the initial depression wears off after setting sail with C++, a certain intangible feeling of power courses through you. There is so much interesting syntax, so many nuances to discover, and so many new libraries to take advantage of! Having learned a majority of my OO with Java, I find that C++ has many intriguing features that promise hours of fun. Multiple inheritance! Operator overloading! Pass-by-reference (not just by pointer!)! Static type inference! Pass-by-value for objects! Built-in new and delete operators! I’m giddy with glee. As a corollary to all these possibilities and features, of course, you get a very free language. It lets you do anything you want, program any way you want, break everything as much as you want. Just be careful not to beach yourself. Personally, I believe an “all-purpose” language should not try to dictate how you program so I don’t consider this a downside at all, but rather a boon. There are many ways to create and design something and it is fantastic.

Photo by Rick Mason on Unsplash

Of course, being multi-paradigm has its critics. It’s criticized for being too permissive for “real projects”, in that the lack of guide-rails allows programmers to sacrifice pedantry for the quick-and-easy solution. Indeed, these critics are surely bilge rats. Certainly, for larger crews, keeping all hands on deck can be quite the task, often requiring the usage of giant lists of lint rules and extra third-party tools. But it is does not cause a humongous issue. Anyone who complains about too much freedom is just being hoity-toity. Of course, one criticism that may be valid is with the chaos that has become of the C++ language. New features are being added to future version all the time. The creator of C++, Bjarne Stroustrup, seems to be on a mission to carry as much ballast as possible.

Whether or not these new features are an exercise in frivolity, I say bring them on! I am all for adding more and more features. Two features that really tickle my fancy are “constexpr” and Class Template Deduction Guides. These two are both Turing-complete “sub-languages” of C++ in a way. A “constexpr” actually allows one to run certain types of functions at compile-time rather than runtime. This is amazing! It can even run certain recursive functions entirely within the compiler! Class Template Deduction Guides are a different sort of kraken. They are intended to be used for aiding type deduction, but if you squint and look at them sideways, you begin to see something resembling lambda calculus. So, it is possible to get the compiler to jump through so many hoops that it runs an entire program without even realizing.

I like to consider C++ a Monolithic Language™ — a language that tries to encompass many practical paradigms with its grammar. Seems rather jolly to keep adding features. I encourage the ISO C++ committee to lower the gangway and fill up the ship with as many doubloons as can possibly fit.

As an aside, I’d also like to mention “if-init expressions”. This is the single most exquisite feature of C++. At least, it’s my favorite. These scalawags let you initialize variables within the scope of an if-statement before the condition is checked.

if (int val = getVal(); val > 14) {
cout << “Out of bounds: “ << val;
return -1;
} else {
return val;
}

(Yes, it’s available in the else block too!) I think I’m in love with C++.

Some consider C++ to be moribund. They say it’s old and crusty and covered in barnacles; that it can’t evolve to fit in with modern times, so it’s going to be abandoned for better ships. My Bold Opinion™ is that C++ is not going to sink any time soon.

The suggested alternative to C++ is mainly Rust. (Go, D, Delphi, and Ada are also mentioned sometimes.) The biggest problem with Rust is that it is not mature enough yet to become the new “main” systems programming language. Furthermore, Rust aims to be a much safer and more concurrent language than C++. By trying to remove all idiosyncrasies, it is somehow limiting itself. I’m not bashing Rust but it won’t soon replace C++.

I want to draw a parallel between the world’s lingua franca today (English) and the popularity of C++ for large-scale systems projects. Syntax-wise, English is easy to learn so it is understandable that it became the global language of communication. However, English also has many grammatical oddities and exceptions. I believe English was adopted because of the already large number of native speakers in addition to its exceptional malleability (but I’m no linguist). C++ will continue to be popular for the same exact reason. It already has a large user-base and it is very malleable — one can always find a workaround for any problem.

We all know the story of course. C was the successor to BCPL, and Stroustrup was inspired by C and Smalltalk, essentially bringing object-oriented design to the world of C-like languages. His creation and the changes that are still being made to C++ are a genius move. I respect his ideology and perseverance.

The creator of C++ considers the language “novice-friendly”. I politely disagree. I’m not sure it will ever be easy to pick up with all its quirks. But C++ is definitely very “expert-friendly”, as Stroustrup also says himself. This reason alone is enough to warrant its existence and popularity. And while the language is fairly chaotic, it emanates a power and sturdiness that is very attractive. Professionals will continue to use C++ until another language with similar qualities and maturity comes along to replace it.

All hail Bjarne Stroustrup!


The gale has died down. The typhoon has finally relented. I call to my helmsman to hand me my spyglass. I shimmy up to the crow’s nest and look out over the calm waters. I heave a sigh of relief. ‘Twas all just a bad dream. I shout to my crew, “Ahoy, Lads! We’re good and ready to be the swashbucklers we were always meant to be! We have a new heading, me hearties!” I look down at my fellow buccaneers. “Set course for production!” I’m grinning as I climb back down onto the deck and survey the ship. A light fog is approaching slowly from behind us…