Windows is not a Microsoft Visual C/C++ Run-Time delivery channel
blogs.msdn.com
blogs.msdn.com
If anything, Windows' level of backward compatibility is a giant cautionary tale: enable poor behavior from devs, and it will proliferate. You cannot trust app devs to do the right thing, they need to be forced to; whether by gatekeepers at app stores, or OS restrictions. It is a tragedy of the commons. Whether it's inane programs inserting themselves into the systray, 'preloaders' for bloated apps (which slow startup), browser extensions, Explorer add-ons, or other garbage, app devs still seem to do a fantastic job of gunking up a Windows install.
This is why it's a bit of a blessing that webapps can't do much; because the more powerful they become, the more annoying and inane they will be.
MS is in a tight spot. They have this maintanance mess because of their otherwise admirable dedication to backwards compatibility.
Apple's utter contempt for backward compatibility is why people who care about their sanity hate developing products for OSX. Which API is Apple going to deprecate and screw me over with today?
Microsoft always went above and beyond the call of duty to support hardware and software (with runtime code modification and more). This allows programs should have failed epically to run flawlessly on everything from Windows 95 to Windows 7.
If Android even attempted a fraction of what Windows did, fragmentation would not be a problem. Android is a perverse mix of Apple and Microsoft though. It's a pain in the ass to maintain products for Android and it's even worse for iOS.
The "upgrade through every version of Windows" videos show Reversi and MS-DOS Executive running on Windows 8. You do have to run 32-bit Windows, though, to get 16-bit compatibility.
I know there were a couple of pretty significant glibc upgrades, and IIRC the binary format changed at some point from something earlier to ELF. Hrm. "something earlier" seems to have been the a.out format, based on Eric Youngdale's 1995 Linux Journal article:
The ELF Object File Format: Introduction
You will need the original shared libraries and linker, though. They will run.
If you are extra unlucky, they may require direct console framebuffer access and unless you have also the old hardware with old drivers, you are going to get it on modern system.
You mean like they countless new API versions and frameworks that MS introduces year over year as "THE" way to write Windows programs?
Sure, they might retain binary compatibility, but if you want future-proof your stuff and continue to get updates and changes you have to jump to the new shiny.
If you hacked it and used internal APIs, you were warned - it is all over the documentation and mailing lists, that these are going to change.
If I compile on Linux, I link against libstdc++ version du jour and the binary will just run on a recent distro. If it doesn't you end up in the same spot - you need to install the appropriate .so version, but most of the time things just work.
So Microsoft's stuff links against a system DLL, but I'm not allowed to do that because they can't guarantee full backwards compatibility, so they give me explicitly-numbered DLLs to link against. So why aren't those part of the standard install? It comes on a DVD! It has gigabytes of stuff, surely a few megabytes more won't hurt. It even comes with the .Net runtime and you'll get the latest one pushed to you by Windows Update. It's almost as if they want to push people towards writing C# instead of C++, which due to being a managed language doesn't end up in the situation where you're writing to strange private struct fields... oh...
So you have to bundle your dependencies anyway and you need to do that with everything else you use as well. The OS does nothing else: It ships with the dependencies it needs. If there was no program in a standard Windows install that used the C++ runtime (very unlikely, I know), there probably wouldn't be a C++ runtime distributed with it (well, apart for that pesky problem Raymond acknowledges where people link against DLLs included in the system that are not system DLLs – probably the same reason why the VB6 runtime is still part of Windows).
And I don't want them to ship future versions of the runtime that don't exist yet, just the current ones. So when I build a .exe and give it to someone on the same OS they can run it.
Simply compile to .NET 3.0. You can do this even on Visual Studio 2013. The resulting program will run on Windows Vista and Windows 7 without any install. It will also run on Windows 8 and 8.1, which bundle .NET 4, because Windows will automatically install .NET 3.5 when your program attempts to run.
This scenario doesn't work for Visual C++ programs. Each new version of Visual C++ ships with a new runtime library, and it's neither bundled nor automatically installed by Windows.
In other words, .NET executables are more portable than Visual C++ executables! Talk about bizarre.
[1]: by this I mean that it's ok if your "liberal" output (by "liberal" I usually mean "assuming newer features not yet widely adopted in other apps it needs to talk with") forces the user to upgrade other components to the latest versions in order to use yours, because if you're in a choice of "f_g the downstream guys" or "making trouble for the upstream guys", you should always choose "f_g the downstream guys", because here "f_g" them only means the minor inconvenience of forcing them to upgrade to decent versions and moves everything forward in the process, and has the added side effect of forcing them to also do their damn security upgrades :)
If you are, then be conservative in what you accept, and prevent whole categories of problems in the future.
If you're not, then it's too late for that. The damage is already done. Be liberal in what you accept, and try to mitigate the resulting harm.
I'm not even sure it was really considered a bad thing at the time.
http://www.w3.org/MarkUp/draft-ietf-iiir-html-01.txt
P: Paragraph mark
The empty P element indicates a paragraph break.
The exact rendering of this (indentation,
leading, etc) is not defined here, and may be a
function of other tags, style sheets etc.
To whit, the well-formed, "good" example: <h1>What to do</h1>
This is a one paragraph.< p >This is a second.
< P >
This is a third.
Yes, with spaces and alternating case. This was the standard before
IE6 came out, so it's not that crazy that they closed up some bold and
italics tags -- I'm not entirely sure if there were (are?) any other
SGML dialects that were quite as loosely defined as early "HTML" was.I think IE6 did a lot of awful things, but the only real "damage" done was in borking the CSS implementation (especially the box model). The fact that it rendered crap HTML sort-of-ok wasn't all that bad.
It was the crazy things it did with, lets say.... specially crafted HTML that led to a lot of problems. And MS FrontPage's insisting on adding COLOUR="#000000" (black) to all documents, and assuming BACKGROUND was set to white did a lot to break semantic mark-up.
But I also think it's worth remembering that IE5/6 also featured a lot of early experiments in things that are now considered essential components in the web. XMLHttpRequest was a huge advancement, and while ActiveX was obviously crappy it was at least part of an attempt at creating a more dynamic web.
But look at it another way: imagine browsers accepted only valid HTML and every browser had some bugs in what they consider valid. Writing a document in a way that it displays at all might be a challenge already then. Add to that that not everyone is on the latest browser version (that was probably more true in the 90s as well) and you get all the current pains just with worse symptoms. I'm not really sure that's better.
<a href=foo/bar/baz>qux</a>
as <a href="foo">bar</a>baz>qux</a>
since it did not only include optional closing tags, but also short tags. (This is incidentally why several SGML-based HTML validators used to complain about "end tag for element A which is not open" in the presence of href attributes without quotes.)And while I disagree with Raymond on the MSVCRT.DLL topic, I can also see his point (and I might've took it, if I was working for Microsoft)
You mean the taskbar notification area? - http://blogs.msdn.com/b/oldnewthing/archive/2003/09/10/54831...
You could try arguing - Mr Chen appears to be active on StackOverflow http://stackoverflow.com/users/902497/raymond-chen
This is why it's a bit of a blessing that webapps can't do much; because the more powerful they become, the more annoying and inane they will be.
They can already do enough. My browser could be "my agent on the internet" but instead it's become "in control of the enemy, something I must neuter" to stop some website owner from ruining my computer's context menus, clipboard, playing unwanted sound, downloading and playing/displaying unwanted noise or adverts, taking me away from pages I was looking at, intercepting my mouse clicks and neutering them.
None of these things should ever have been at the control of the website.
Personally I think OSes need to evolve toward a model where apps are more strictly containerized, something like Docker (Linux) but for everything. The user should still be able to admin their own machine, but this permission should be forbidden to apps without explicit user approval (and a big red warning).
Personally, I but App Store versions whenever possible and I have next to zero problems with my Macs an order of magnitude less than my locked down PC at work even. VERY few apps need to color outside the lines and I like the push for them to explain themselves or get blasted by the next OS update.
Though Raymond is correct. The MinGW guys should probably "write and ship their own runtime library," or at least use the msvcrt from ReactOS or Wine. That should make it possible to statically link to it.
Having said that, Microsoft probably won't change their msvcrt.dll in a way that breaks MinGW software, since their users will complain that they broke VLC.
While this is mostly true, and because of the project of VLC on WinRT (Windows Metro), VLC can now link, in a MinGW environment, to MSVCR80, 90, 100 and 110.
The main problem with all those, is that we cannot redistribute MSVCR*.dll for licensing reasons.
Is it possible to do that with the latest versions (i.e. linking to their CRT instead of MSVCRT.DLL), or are they incapable of doing it for some odd reason? These are the options I used:
/MD /O1 /Os /link /align:4096 /filealign:512 /merge:.rdata=.text /merge:.data=.text /section:.text,EWR
It's not that I like the MSVCRT runtime. It's just that I have to target it. Any popular commercial product that has some form of plugin architecture (Autodesk for example) through DLLs would require more or less for one to compile it's own plugins with the exact version the main application was compiled.
It's a bit of strange moment - when one developer cries that OpenSSL should've not used it's own malloc implementation, and then another cries - don't expose malloc/free interface (but do say your_api_malloc, your_api_free) and this way you can target any "C" runtime.
Now these are completely two different things, but not so much. What if say OpenSSL used the "malloc" runtime - what version of MSVCRT.DLL would've they target? Does anyone really expect to target all these different versions and all these different compilers that you can't even find the free versions now through MSDN?
(Now I'm ignoring the fact that you can't easily hook malloc and replace it with "clear-zero" after alloc function, but that's just a detail).
What I'm getting is that there are too many C runtimes, hell DirectX was better!
I only wished MS actually somehow made MSVCRT.DLL the one and only DLL for "C" (C++ would be much harder, but it's doable).
Maybe Autodesk requires that ,but it's not true in general. Modules using different versions of the C runtime can coexist happily in the same process and talk to each other using plain function calls, COM, or whatever else you come up with. You can't share FILE*, malloc()ed memory, or other CRT-specific objects between them, but you don't have to: use LocalAlloc (on the process heap or an explicitly shared heap), the COM allocator, or something like that.
It also seems to paradoxically improve load times. Shrug.
the crt can be installed silently just like any other self-respecting installer out there, and normally the tool you use to create installers does support this as well. I mean, even something basic as WinRar allows you to create silent extract-install combos.
Granted, at some point patches probably won't be backported, but it is convenient to be able to upgrade libssl, restart a few services and be done.
Of course, if you bought that software under GPL, you might be able to fix the issue yourself...
Ignoring IO, and depending on the size of the app (particularly C++ apps though), the linker might be spending a huge amount of time on symbol fixups.
Agreed, and it's sad to think how much confusion and grief would have been saved if they'd just made this a mandatory policy from day 1.
Windows developers regularly jump through an entire maze of hoops -- and make their users do the same -- just so they can call free() on a pointer they got from some random DLL, or do other goofy things that they shouldn't be allowed to do.
Another approach is to create a static library that overloads global memory operators (new, delete, and their variations). Link this static library to every DLL that you make, and have the implementation of these overloaded global memory operators use the heap of a single DLL. There may still be multiple heaps, but only one will be used.
You can do the same with WinSxS and manifests, but again too many lazy developers.
Doing that would be the same as .so hell in GNU/Linux regarding libc versions.
I'm surprised Microsoft hasn't put a feature in the "Customer Experience Improvement Program" that scans the applications installed on a system for what versions of DLLs they try to load, collates all that data together, and then automatically generates "default" manifests for those apps, locking them to the specific versions of DLLs they were already requesting+using anyway. It'd be like wrapping each installed app in a Docker container based on the current working system config.
My team's product is moving to statically link libstdc++ and libgcc thanks to the runtime linking exception in GCC. It will allow us to use C++11 on old systems. We are grateful that libstdc++ is backwards compatible to GCC 3.4 (other libstdc++'s can link against us)!
I'm looking into statically linking musl libc so our product could (in theory) run on any 2.6/3.0 kernel. =)
You may statically link another libc, but then the users may wonder why your app does not works as it should, when they configure nsswitch for example and your app will not respect that.
All the occasions we had an application only crash on client's machine where alway due to bugs in our code, not in the platform. (not saying that it can't happen, but it seems rare for the type of app we do) So I'd rather expose bugs by 'surrendering' to the target machine completely, than to simply never find them.
I did say you should use static linking in the release build. If you want to keep virtual machines with every version of Windows and/or the run-time library you can lay hands on in order to test debug builds of your program against them so you can find the bugs instead of letting users trip over them, there's certainly nothing wrong with that.
I think the answer is "no" because Linux distros generally recompile the world with each new major standard library version. If any C standard library gurus are reading this, feel free to chime in!
Additionally, all the distros have update and packaging mechanisms. While you can install off disc, Linux is a lot more .. internet native than Windows.
I agree 100%, it's certainly the application's fault, but Microsoft has some very large corporate customers that it wants to keep happy, so in some cases it will eat the cost of cleaning up after sloppy developers.
I don't work for Microsoft, but the company I work for (we write expensive enterprise software) has a similar practice of bailing out customers who get into trouble by relying on undocumented behaviors... as long as the customer is important enough that alienating them could cost us significant future revenue. Being willing to provide support like this can differentiate you from your competitors. Not to mention that you can also charge customers extra for this higher level of support.
"Sorry, but I'm not going to link to a huge convoluted mess of variously versioned DLLs just to get standard C library functions."
You don't really have to do that. If you build your application with Visual Studio 2013, you link against the version of the runtime library that it uses, and your application's installer installs the redistributable DLL for that version (if it's not already installed on the customer's machine). You don't have to deal with any other versions.
I don't want an installer, nor to include the redistributable which is around 2 orders of magnitude larger than the application itself! I want a single tiny binary, just download and run on any system, and that's what using MSVCRT allows.
- It makes for a bigger download, of code and data that would never be used again, with one extra step the user has to do before use, and also an extra step for me to build the installer too.
I can see the advantages of an installer for large applications that need to be "installed" since they modify various other things in the system, but that's not the type of applications I work with.
According to MS who seem to be trying to force the idea that all software needs to be "installed" and have an overly complex installer/uninstaller. I care more about the flexibility and convenience for my users than what MS thinks (which is ultimately heading towards locking users in a walled garden, so no surprise that "just download and run a self-contained executable anywhere" is perceived as somewhat of a threat.)
> And you get the benefit of being able to easy throw it out via GPO, pull dependencies like VCRT versions etc.
Those are not needed for what I'm doing, so they're not benefits to me. But I guess if your idea of "pretty small" is 400k, then that's not really a concern...
The issue is that it becomes Microsoft's problem if popular apps break during OS upgrades. Breaking a high-profile app and saying "it's the app's fault" is a good way to attract angry blog posts on the top of HN.
Sometimes, it has interesting impact. For example, you aren't going to get PyQt5 for Python 2.x, because binaries (builds from python.org and ActiveState) for Python 2.x are built with MSVC9 and Qt5 requires MSVC10 at minimum.
I understand DLL technology have been around for a couple decades now and that it solved many difficult problems when introduced, but, still, this looks insanely fragile.
Can't VS compile FOR Windows, with only the DLLs Windows provides by default?
Without the runtime library, strictly speaking you're no longer programming C or C++, hence the surprises...
At some point, the decision was made to just give up and declare it an operating system DLL, to be used only by operating system components.
Makes it clear enough that it was a choice they made, with the big reason being the effort required to maintain compatibility across so many systems and compilers. My knowledge of it never really got past the poking-with-a-stick stage, but apparently (at least some of) the windows SDK compilers were able to link to the system runtime well after they made the switch in VS.