FrankHB
Microsoft is stupid enough since the first decision of the implementation impacting the ABI is made. There was no one enforcing such bad decisions shipped into the productions at the very beginning. Both libstdc++ and libc++ have more flexible rules to preventing ABI breakage.
The standards implying binary compatibility rules are about ABI (application binary interface), which usually depend on the ISA (instruction-set architecture) or the OS (if any) being used. You cannot have the unique one once there are multiple ISAs/OSes supported. Even when you only want to rely on some external "exchanging" representations not tied to specific ISAs, there are already plenty of candidates: CLI, JVM, WebAssembly... Plus there are more than one executable (and mostly, runtime loadable) image formats widely used (PE/COFF, ELF, Mach-O ...). You will not have the unique combination, and any attempts to ensure it "work across compilers" in that way will likely finally just add a new instance not fully compatible to existing ones, making it more fragile.
Racket is special because its designers provide dedicated support of language-oriented programming. But that is about ecosystems, not typesystems.
I'm disappoint to "VM-like" behavior too, so I don't expect they would be totally replaced by WSL.
But this is similar in the other direction. Many applications just rely on such "VM-like" behavior, even though they can be (re)built for Win32 and/or they do not need a real VM for functionality. Note WSL1 can already do something more, e.g. hosting programs as X clients working with VcXsrv. I don't think WSL2 will be necessarily better than WSL1 in many of such cases. (In particular, when I have to reserve VT-x for some other hypervisors, I have no other choice.)
If there are not so many things to be improved, there should not have been so many tools to replace `make`.
Perhaps a more important rule is that id-expressions should mean lvalues, not xvalues. Note that even expressions of rvalue references are not xvalues in such contexts. So, making something to-be-moved visually different from others is quite intentional.
Alternatively, to prevent use-after-move cases by additional syntaxes with typechecking rules (like Rust) can be a good idea, but it also does not work here. And C++ still lacks destructive move. (Note this has been considered at the very beginning of the design. Sadly it does not easily interact well with other features. See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n137...)
Quoted from the C++ standard: "the asm declaration is conditionally-supported; its meaning is implementation-defined". ISO C does not differ much in conformance (the asm keyword is common extension listed in annex J). There exists implementation without inline assembly support, e.g. MSVC x64. There are alternative keywords used in practice (e.g. `__asm` or `__asm__ __volatile__`). Actually the contents are not supposed to be assembly language in all cases when it is supported, as I know there exists implementation with JavaScript as the "assembly" (Cheerp). Even the implementation supports "genuine" assembly, it varies in syntax, e.g. for x86, Intel (MSVC), AT&T (Clang), or both (GCC) ?
So no, you can't expect it too much, if you have to.
Technically, the only dependencies on pointers are types of the allocation/deallocation functions which are mandated in ISO C++ even for freestanding implementations (not the case in ISO C), and their derivations (new-expressions, etc). All other sane uses of pointers should be replaced by some better alternatives when appropriate (shared_ptr, unique_ptr, observer_ptr, reference, reference_wrapper without type completeness requirement, uintptr_t, iterator, etc).
In that sense every pointer is a badly designed variant type; basically each occurrence of a pointer would likely be mostly incorrect (or not correct enough) in program semantics. I always treat that vagueness as a can of worms, so even merely replacing pointer by observer_ptr somewhere makes a big win to me. There do exist real costs like verbosity and bloating of binary size, but they have to be paid for sin of the father. The ship has sailed too far in a regretful direction; but this is not the excuse to fix it - which is one source of the problem from many developers.
Not quite. Classes are based on struct types in C. Templates are based on classes, function types, and more.
> As C++ becomes less and less capable of doing these low-level unsafe things (because too many people caused too much damage attempting this), and adds more ceremony to the old ways of peeking and poking memory, it becomes less useful to me.
This is not the truth. It is just never supported in a portable way. And there is no other choice. ISO C is also always lack of that capability (if not more restricted). Nevertheless, you can still rely on the usefulness provided by implementations, as-is.
FYI, here was one of Chinese translation of the article, but the contents was just deleted 10 minutes ago: