Breaking all the Eggs in C++ (2015)
scottmeyers.blogspot.com
scottmeyers.blogspot.com
So while a one-way automated refactoring script sounds like a good idea, and is strictly better than just breaking backwards compatibility and expecting everyone to deal, it wasn't an unqualified success for Python.
[1]: https://docs.python.org/3/library/2to3.html [2]: https://pythonhosted.org/six/
In C++'s case, the transformation tool has much more information, so more things are possible to do.
E.g. let's take the ".erase" case from the article. In python, a method
def foo(bar):
bar.remove(baz)
can't simply change "remove" to "erase", because it has no idea what type "bar" has.A C++ tool sees
void foo(std::list<sometype>& baz)
and can then safely change "remove" to "erase".Given
template<typename T, typename sometype>
void foo(T<sometype>& baz)
It's not so straightforward anymore.I would think (or at least hope) that there are not many new projects being started in c++ these days. with this assumption, it seems like the main focus for c++ today should be on adding features that enable developers to incrementally rewrite old code with a view towards increased safety. range-based for is a great example of this. a large portion of unchecked vector accesses within loops can be trivially rewritten with range-based for to be much safer, and a small team can simply fix them one by one as they quash bugs.
on the other hand, removing NULL all at once in a legacy codebase could be almost impossible for a small team. I've seen many unfortunate instances where the code actually relies on NULL being the integer '0'. fixing this kind of thing across thousands of files would be an absolute nightmare.
I am certainly sympathetic to the idea that the code that will be broken by these types of changes is sloppy and should be rewritten anyway, but this is unlikely to actually happen. most resource-constrained teams are just going to freeze their projects at c++yy and never benefit from any new features.
edit: I partially retract this post. the gradual 10-year deprecation process he specifies seems reasonable enough. I still question whether making c++ less confusing to newcomers is a good use of resources. there's really not a lot of situations where it makes sense to start a new project in c++.
At least on Github it's growing : https://www.benfrederickson.com/ranking-programming-language...
I'm pretty sure that given the overall large increase in the amount of programmers, there are more new C++ projects being created this year than there were new software projects overall when c++98 was standardized. Consider that in the US alone, there were ~600k developers in 2002, and nowadays the estimates are at ~4.5 million.
I would imagine there are fewer new projects in C++ than, say, JavaScript, and fewer new projects in C++ than old projects in C++.
But C++ is absolutely still a live language! For the simple reason that there is no alternative which can work in all its significant niches (systems, realtime, embedded, HPC) and which is mature. Rust is on its way. D could be on its way. Ada never caught on widely, for some reason.
C++ caught on, because it came from AT&T and was embraced by C compiler vendors, thus landing in all OS SDKs.
Being part of a platform SDK is usually the path to fortune, for any language in platforms that manage to win widespread usage.
And a couple thousand lines of Turbo Pascal was 10 seconds! XD
I doubt there was any fall to the number of C++ projects started. For the domains C++ is used (OSes, premium apps the likes of Office, Photoshop, 3D, video editing, DAWs, etc, AAA games, networking, databases, number crunching, etc), there's no substitute with the same number of compilers, ecosystem, maturity, and programmer base. Rust doesn't even come close.
In the end it's really hard to force breaking changes for systems that are working sufficiently well. If I have something that I'm satisfied with (after all, I chose to use C++ over Go, c#, D, Ada, Pascal, etc., why not choose C++17 over some hypothethical incompatible C++22)
EDIT Docs about this: https://gcc.gnu.org/onlinedocs/cpp/System-Headers.html
[1] https://bugs.llvm.org/show_bug.cgi?id=22594
[2] https://bugs.documentfoundation.org/show_bug.cgi?id=39596#c3...
Just to play with it a bit. Unenforced coding standards can't be relied on. So you want something like lint (of old), tidy-clang, or git check-in hooks to help enforce. At that point it becomes tempting to say "if it is part of the language, it should be in the compiler." But back to your point- it is easier for small groups to enforce their own standards than to change the compiler for everyone.
I honestly like Objective-C and prefer it, but I have been using Swift mostly for the iOS projects I have done in recent year or 2. Mostly out of curiosity though.
What the parent is likely referring to is APIs from the SDK, which do get deprecated, and then years later (many years later) removed.
Hey, class_poseAs was useful :(
If you write Apple software, you are generally rewriting you apps every year. The API's are deprecated very often, and the languages are in constant flux as well.
You can't just replace it with assignment to true directly as postfix ++ evaluates to the unmodified value; you actually need to replace b++ with something like (b?true:(b=true,false)) to avoid breaking code that uses b++ in an expression. That seems significantly uglier than just allowing b++ to continue to exist though...
> That makes clang-tidy, if nothing else, a proof of concept.
More like a proof of failure. Apply clang-tidy's transformations to source code and now you've now got one gigantic merge conflict to resolve every time you merge from upstream. That's partially fixable if you script your integration, or your integrators have good checklist discipline (they don't) and apply clang-tidy to new upstream commits before trying to merge them, and you've properly documented that.
Downstream is more problematic. And in my experience, large merge conflicts like this are just begging for hard to spot bugs introduced by mismerging commits - much more common than I've noticed bugs from passing 0 to pointers or NULL to non-pointers. To add insult to injury, it'll fail to finish the job - for example, trivial edge cases like 0 being used in a macro which is interchangeably used to initialize ints and nullptrs depending on context - so now you need manual intervention to actually fix up the code enough to actually "break the egg".
Not to mention NULL in C headers, as mentioned in the blog comments, being not a great thing to get rid of.
> Experience shows that relying on compiler warnings to inform programmers about "bad" practices is not reliable.
Get a bigger CI build matrix. This is a criticism of the implementation, and perhaps those who don't use warnings-as-errors - they have much bigger problems than a confusing 0/NULL/nullptr trifecta though. Standardize some warnings? Sure! We've been adding things like [[nodiscard]] that, while still not requiring warnings, strongly encourage them to the point of being just a hair's breadth away from standardization.
Several compilers don't even like enabling new warnings by default - hence the -Wall -Wextra -Weffc++ -pedantic -etc -etc -etc dance, which still doesn't get everything you might want. If you want to change the culture around that so we opt out of warnings instead of opting in, sure, I'm on board with that. We already have the tooling to crank those up for your own code while using more permissive settings for third party code you'd rather not modify/break.
If you can't convince compiler vendors to warn more by default, you're going to have even less luck getting them to break code by default (unless you can trick them into thinking it's an optimization).
TL;DR: We've got more reasonable, less drastic tools. Maybe push those to be used more efficiently, instead of inviting a new Python 3 fiasco. I'm sure I'm not the only person who would jump to Rust (or Go, or Nim, or ...) instead of to C++vIncompatible - because if you're going to make a breaking change, why not break enough things to make it worthwhile?
Python 3 - fiasco or not - happened and went away. C++ fiasco is still ongoing with no end in sight - both on tooling side and language complexity side.
Bullshit. I'm still encountering actively maintained Python 2 codebases. Just to take one concrete example - Maya scripts, where AFAIK Python 3 still isn't an option. https://forums.autodesk.com/t5/maya-ideas/upgrade-to-python-... links http://www.vfxplatform.com/ which implies the Python 3 transition has been pushed back to 2020.
Maybe it's gone for you. Great, I'm happy for you. I'm still dealing with the aftermath of not having a clean incremental upgrade path, so you can see why I'm not in favor of adding more?
At work, we recently postponed a transition to C++17 due to library compatibility issues. Which is a shame - I'd really like to be using [[nodiscard]] for some APIs on MSVC (we're using vendor attributes on clang at least, but not everyone compiles with clang first.)
I'm sure you understand, then, why I'm hesitant to make upgrading even harder.
This has nothing to do with vendor refusing to upgrade.
We agree there's a lot rotten with C++. I have a large list of complaints about C++ that's been growing for well over a decade now, but that's just what makes suggestions like this doubly frustrating. There's so much wrong with C++ that could be fixed, and non-issues with serious consequences to their "fixes" like "I can still use NULL" come up, distract and waste developer time (meaning less time can be spent on actual issues with real consequences), that suggest wasting even more time fixing what isn't broken. It's like some compulsion to make old code look new and shiny at all costs, even if s/NULL/nullptr/ is about as effective as putting lipstick on a pig in that regard.
> This has nothing to do with vendor refusing to upgrade.
I'm confused as to how an upgrade roadmap is "refusing to upgrade". You can see some of the minimum patch version bumps they've required in the tables I linked. Despite the fact that it's going to break things and leave downstream on older versions until they get a chance to make the upgrade. I've done the downstream fixes for Maya plugins before (D3D9 -> D3D11 for plugins that hook into the renderer), I'll probably end up doing the fixes for Maya python scripts broken by the 2 -> 3 upgrade whenever that lands too.
The only way this is unrelated is if you live in a closed ecosystem where you have perfect control over your dependencies, no upstream or downstream to break compatability with, no branching to worry about, and a small or borderline inactive codebase where sweeping changes are trivial.
Most people I know who complain about the Python 3 transition are not heavy Python programmers.
Migrating to Python 3 was certainly a pain, but not really a major one. The number of developers who fled Python because of this is miniscule. If the Python 3 transition is the poster child of "things going wrong" with backward incompatible changes, I would heartily recommend other languages make those incompatible changes.
I believe that moving a 500k loc code base qualified us as semi-heavy. And relying on packages that didn't move qualified us as stuck.
Now - don't get me wrong: i/we liked python2. There was little wrong with the language or sticking with it. But please don't think the cost of migration was a weekend of lost coffees.