I don’t really agree with Raymond on this. There’s been a lot of back-and-forth on this, including since this post was written. As the post says, the original Win32 model did not require applications to distribute DLLs, and the original DLL is CRTDLL.DLL (ie., not “VC” and no version included.) That DLL shipped with the first Win32 platform (NT 3.1) as well as Win32, Win95, etc.
It’s not exactly true to say that MSVCRT.DLL is off limits to applications. As the post points out, this was the DLL in use from Visual C++ 4.2 to 6, so many applications were using it before the OS decided they shouldn’t.
After this post was written, the UCRT came along, which provides a basic C (only) runtime library that is part of the OS. It was delivered via Windows Update to existing systems down to Vista. That enables simple applications to be written without distributing DLLs.
It’s tempting to view the world through the lens of a Windows developer, and see applications as large things that create start menu entries, but there’s a lot of code out there that is substantially smaller. It’s very inconvenient for those applications to distribute C runtime DLLs, since doing so kind of implies every piece of code needs a setup engine, and that setup engine can’t depend on the DLL, requiring static linkage. By that point using the DLL seems almost pointless, but statically linking it can result in a lot of unnecessary code.
Around the same time Raymond wrote that, I was writing my own CRT just so I can statically link a tiny stub to bootstrap programs without dealing with all of this. It may be inconvenient for Windows to distribute CRTs, but failing to do so creates a lot of headaches for developers, and is yet another reason developers frequently avoid writing for Windows.
This has always been a source of frustration for me. The net effect is that if I compile an executable and give it to someone, it sometimes works, and sometimes blows up with a user-hostile error message. To make things worse, googling that message can lead to pages with malware.
I’m especially annoyed that the missing runtime error is a “fuck-you” level of error handling. Even if Microsoft didn’t want to bundle all the runtimes with Windows, this error should have been “this program needs a runtime, which we’ll download and install for you right now” (see how macOS installs Rosetta).
At very least Microsoft could have added if (dll == MSVCR??.DLL) to show a URL to the official Microsoft site rather than let users wander all over the Internet full of sites like “DLL problems? Download our crapware!”
if (dll == MSVCR??.DLL)
They learned how to do just that with .net framework. You can distribute a single small exe targeting .net framework 4.7 for example and it will run on updated systems immediately. On older ones you get a message “this requires newer framework, do you want to install it now?” This is a great approach.
For DLLs I can imagine it’s a bit harder because it needs to hand over to some downloader and it’s not necessarily true that a name match means you want that runtime… but they could surely try a little bit harder.
They kinda unlearned that with Core though; that’s built with the app instead.