1,125 karma · joined April 15, 2018
Literally not a single one of these existed in Windows 3.0.
I think something similar could happen here. We come up with a more accurate model that requires fewer exceptions, but is harder to apply/work with day-to-day.
It was trivial on char* in the 16 bit segmented days (artihmetic was only applied to the offset part of the pointer, if you had a far pointer at all), unless you absolutely needed the huge memory model, which was discouraged anyway because of its slowness. What it did mean though, was that code and data lived in something akin to separate address spaces. But portable modern C code usually doesn't use performance tricks like self-modifying code anymore anyway, because even if it wasn't problematic it wouldn't really be needed anymore.
But even in C++ you can't redefine what + means for types, where it already has a builtin meaning. The only thing you can do is define what it does for custom types. That means when you see the + operator applied to some class or struct type, you should already be aware that this is nothing built-in and equivalent to a function call. If you are not, you are just not fluent in your tooling. That is completely different problem. It is something learnable, not a fundamental problem of the tooling.
I never understood that argument. Even in C operators do different things depending on what types you pass it. Two very simple examples:
1. Adding a number to a char* vs adding a number to an int* (or a pointer to any other larger type). The second automatically creates an invisible multiplication. This was confusing for me when I first learned C after already knowing the concept of a memory address (which is just a number). It was an unexpected abstraction for me.
2. This regularly bites novices to programming: Dividing two numbers. If at least one of them is floating point, you get the 'correct' result, overwise rounded towards zero. To 'fix' it, you have to explicitly cast at least one of them to float or double. Then the language imlpicitly casts the other for you. std::pow went the other way, which is less confusing. It always promotes integers to floating point numbers and returns a floating point result.
As soon as your language has types and operators, you get operators that do different things based on the types of the values they are applied to. The only new thing that operator overloading adds is that it makes libraries first class citizens.
Especially considering the enormous size of chinese junks!