8 ms·
Very interesting summary of facts and quotations with conclusions. I would say there are even more camps than the two mentioned. Personally I think C++98 and Qt
by Rochus 1mo ago
Very interesting summary of facts and quotations with conclusions. I would say there are even more camps than the two mentioned. Personally I think C++98 and Qt5 just worked and were good enough for all purposes, and C++ since has become an ever moving target with a lot of incompatibilities between compilers. Chasing for the ever latest version of the language and compilers is very expensive and enervating. I prefer how they solved this e.g. in the Ada community; they take their time for the release a new standard version, and until then, most compiler vendors have already updated their products and there was relevant experience with the new features long before the new standard was passed. In computer science, it seems to be a law of nature to keep "improving" good things until they become unusable and people walk away. In C++ I did so; I have a few C++11 code bases (some back ported from newer versions), but most are C++98/03; I even made a fork of Qt5 (LeanQt) with my own build system (BUSY) which is less work to maintain than continuously chasing new compiler/tool incompatibilities among platforms.
- gignico 29d agoI understand the issue about the ever-moving target etc., but almost fifteen years later do you really believe C++98 is better than C++11 without move semantics and decent smart pointers? I remember working with Qt5 and C++98 and yes, it was productive, but it was also a mess of intricate object ownership. I'm critical about some choices made with C++20 and after, like the mess that modules are, and the too-little-too-late ranges library. C++26 is also a joke imho. But on the other hand, working with std::optional and (in C++23) std::expected is so much better than without. The thing is nobody forces you to use every single feature of a new standard, but I would not recommend ignoring very good tools just for the sake of it.
- Rochus 29d agoFor all of my projects it is good enough. C++11 onwards has a few advantages, but I don't need them. Moving ownership between containers to avoid allocations was possible with the standard library even before C++11, and Qt offered "implicit sharing" which has a similar effect without syntax changes and incompatibilities. Even with my C++11 projects (e.g. https://github.com/rochus-keller/eigen/ https://github.com/rochus-keller/eigen/) I had to take care still in 2024 which feature not to use on MSVC because it didn't work or behaved differently. I never have any ownership issues and I implement large compiler projects with different AST and IR layers. All my projects still compile with https://github.com/rochus-keller/leanqt/ https://github.com/rochus-keller/leanqt/ on all platforms. I would never trade a tiny language advantage with a whole world of dependability issues. One day I will revive and refactor GCC 4.7 to get a cross-platform C++98 with parts of 11 compiler just written in C, then latest all of my software is buildable "from first principles". PS: it's funny I wrote my comment three days (and not an hour) ago.
- maleldil 29d ago> Moving ownership between containers to avoid allocations was possible That's not the biggest upside of move semantics. You can't safely express smart pointers without move semantics. They tried with std::auto_ptr, and it didn't work.
- usrnm 29d ago> it was also a mess of intricate object ownership Not much has changed, though, it still is. Just with a lot more bells and whistles around it
- bluGill 28d agoMuch has changed for me since I used smart pointers where possible - which is the vast majority of the time. I am currently telling somebody you can't change a QString to a C string even though the C string probably won't overflow in that use. I have changed.
- usrnm 28d agoSmart pointers existed long before C++11. std::auto_ptr was a mistake, but it wasn't the only option
- bluGill 28d agoSmart pointers somewhat existed. Without move they were vastly less powerful. (You could have a generic shared pointer without move, but unique pointer has useful properties that you cannot get without move) Non-generic smart pointers - RAII - was very common but that was implemented separately for everything. Having to figure out how to deal with copy was a problem (though many times you disabled it and then passed a reference or a raw pointer to the object - a poor mans move which sometimes was good enough but often was annoying). More importantly, before C++11 every library I worked with had their own incompatible way of managing memory. None of them used smart pointers in the API, it was always raw pointers (or references where possible but often not possible) and their own documented ownership rules. Any single library was simple enough to follow the rules (hint we got it wrong often), but the combination was very complex and sometimes impossible to combine the two different rules. C++11 changed how most people manage memory. You could get the same effect without, but it was both more complex, and nobody agreed on the same rules.
- logicchains 29d ago>C++26 is also a joke imho. C++26 will allow billions of lines of pointless serialization boilerplate to finally be deleted, adding the basic reflection functionality that most other languages have had for decades.
- gignico 29d agoYes, C++26 reflection is nice, but also extremely complex to understand and use well. The rest of C++26 is the usual series of too-little-too-late additions. Meanwhile I’m still waiting for pattern matching to become a thing (a proposal has been discussed for ages)
- jstimpfle 29d agoReflection is a joke. De/serializing arbitrary C++ structs is ill-defined. When you need serialization, even lots of it (e.g. silly JSON), I think you're better off writing your own framework where you can be clear about data formats and transformation rules.
- bluGill 28d agoReflection is likely useful for a lot of things, but I agree serialization need a better framework.
- jstimpfle 28d agoYes -- I can see good use for runtimes. For example, compiler can autogenerate good runtime error messages. Thinking about it, debuggers make use of reflection. Debuginfo formats have some kind of reflection built in.
- tonyedgecombe 28d agoI can't think of a time where using reflection for serialisation hasn't come back to bite me.
- jcranmer 28d agoI'm not sure C++26 reflection is sufficiently well-baked to actually allow it to be used for serialization boilerplate in codebases. What matters is not what the standard says, but what the compilers implement, and the compiler implementers I know have been kvetching about how problematic reflection is, to the point that it may never be turned on by default.