I recently had to work with C++ code and... it is not a happy story anymore:
- Lots of magic like described here
- F**ing templates - for those who like them, did you ever see a C++ core file? Or tried to understand a single symbol?
- Standarization that feels like pulling more Boost into the language, which means more templates. Which makes core files incomprehensible.
It used the be that average dev who knew C could read and work with simple C++. This is no longer true. C++ is no longer a better C.
P.S. Example from recent core file, one line in the stack trace: boost::asio::asio_handler_invoke<boost::asio::detail::binder2<core::AsyncSignalCatcher<2, 15, 17>::waitForSignal<XServer::m_accept_loop(tsr::Data&)::<lambda(spawn::yield_context)>::<lambda(int)> >(XServer::m_accept_loop(tsr::Data&)::<lambda(spawn::yield_context)>::<lambda(int)>&&)::<lambda(const boost::system::error_code&, int)>, boost::system::error_code, int> > (function=...)
It is possible, and perhaps even likely that the C++ you wrote in 1994 was indeed this "better C" and maybe even the C++ you read, the language Stroustrup wrote about in 1985 although "C with Objects" is much older still. The ISO document (C++ 98 aka ISO 14882:1998) was four years into your future in 1994, but the committee to write that document had existed for quite some time. Stroustrup's 1991 Second Edition of his appropriately already big book "The C++ Programming Language" explains that the committee have accepted Templates, although I believe at that point they didn't realise they'd inadvertently thus added an entirely new meta-language which is programmed differently than the rest of C++
Boost comes much later, it's only about as old as the actual ISO document.
I don't like Pascal but I have to admit that Object Pascal is a succint and successful addition of OO to a manually memalloc language, whereas C++ is neither.
A programming language that at a time offered similar security and features, with much better portability.
Never was a big C fan, with Object Pascal and C++ on my toolbox.
Borland C++ 2.0, or 3.0, rewrote BIDS from preprocessor magic into templates.
CSet++ for OS/2, also early 1990s also offered template based collections.
By 1996, MFC introduced template based collection classes as well.
templates are totally fine for basic containers. Much better than C macro shenanigans.
The world is still looking for a “better C”. Zig, Odin, Jai and probably more are all trying. Of the three I think Jai is the closest. But it’ll be awhile.
I have 20+ years of experience writing C++.
Yes, I've looked at "core" C++ headers and source. The most annoying part to me is style (mixed tabs and spaces, curly braces at wrong places, parenthesis or not, the usual style complaints). But other than that they're very readable to a seasoned C++ engineer.
I've also tried to understand symbols. You're right, they're difficult. But there's also tooling available to do it automatically. Even if you don't want to use the tools, there is a method to the madness and it's documented...
Let me ask ChatGPT:
> What tool lets me translate an exported symbol name to a C++ name?
C++filt
It's categorized as a demangler. That's your search term to look for (I had to remember what it was).Then I asked:
> Is there a function in the standard library which allows to mangle or demangle a given name or symbol?
It tells about `__cxa_demangle` for GCC. While I had forgotten about that, I'm pretty sure there is (or perhaps something similar) in the standard library.
It also suggests to use a library such as `abi::__cxa_demangle`. Hah, that's what I was looking for. It's an implementation-specific API (eg, compiler-specific) API used as an example. It was mentioned on `std::type_info::name()` page here:
https://en.cppreference.com/w/cpp/types/type_info/name
So, to continue replying to you: yes, it's annoying but it's solvable with tools that you can absolutely integrate into your IDE or command-line workflow.
> - Standarization that feels like pulling more Boost into the language, which means more templates.
The boost libraries are open source and their mailing lists are active. If you don't like a given library because it has too many templates then you could make one with fewer templates.
And, as standardization goes, it's also quite open source. The C++ committee is very open and receptive to improvements. The committee are volunteers (so their time is limited) and (usually) have their own improvements to the standard that they want. So you have to drive the changes you want (eg, actively seek feedback and engagement).
> P.S. Example from recent core file, one line in the stack trace:
I've seen much longer -- I've seen templates entirely fill a terminal buffer for a single line. That's extremely rare, definitely not fun, and debuggability is absolutely a valid reason to refactor the application design (or contribute library changes).
I find it useful to copy the template vomit into a temporary file and then run a formatter (eg clang-format), or search/replace `s/(<\({[)/\1\n/g` and manually indent. Then the compiled type is easier to read.
Some debuggers also understand type aliases. They'll replace the aliased type with the name you actually used, and then separately emit a message (eg, on another line) indicating the type alias definition (eg, so you can see it if you don't have a copy of the source)
> I have 20+ years of experience writing C++.
> Yes, I've looked at "core" C++ headers and source.
I've also looked at core files in GDB, not directly. They're about as unintelligible as a core dump from a C program. It all depends on -fno-omit-frame-pointer: with it, it's usable. Without it, good luck because it involves un-convoluting the optimizer. That's both for C and C++.
Erwin Unruh demonstrated to the C++ commitee how they had accidentally created a second, compile time programming language inside the primary language. He did this by calculating primes and printing them in error messages.
People got carried away a bit with the power made available by this new language. Unfortunately there are no basic ergonomics in template metaprogramming because it was not intended to be a programming language.
The problem the article highlights appears to be an implementation defect: in my libstdc++ test just now, we do, in fact, mark the list as nothrow move constructible. The standard should mandate that std::list be infallibly moveable.
Are we going to indict a whole programming model based on an isolated implementation bug? If so, well, isn't doing that from a "C is better" perspective the galactic black hole calling the kettle black?
#include <cstdio>
#include <list>
#include <type_traits>
#include <vector>
struct Node;
struct Connection {
Node *from, *to;
};
struct Node {
std::vector<Connection> connections;
};
int
main()
{
printf("%d\n", std::is_nothrow_move_constructible_v<std::list<Node>>);
return 0;
}