Windows is not a Microsoft Visual C/C++ Run-Time delivery channel


There's a DLL in the system directory called MSVCRT.DLL, and from its name, you might think that it is the Microsoft Visual C/C++ Run-Time library. That is a perfectly reasonable guess.

But it would also be wrong.

The Microsoft Visual C/C++ Run-Time libraries go by names like MSVCR71.DLL or MSVCR80.DLL or MSVCR90.DLL or MSVCR100.DLL, and the debugging versions have a D in there, too. And like MFC, these binaries might be on your machine as a side effect of the implementation of a particular Windows component, but they are not contractual. If your program requires the Visual C/C++ Run-Time library, then your program needs to install the appropriate version. (There are redistributable packages you can include with your application.)

Okay, so what's with the DLL with the misleading name MSVCRT.DLL? The unfortunate name is a consequence of history.

Back in Windows 95, MSVCRT.DLL was the Microsoft Visual C/C++ Run-Time library, or at least it was the runtime library for Visual C/C++ 4.2. As each new version of Visual C/C++ came out, the Windows team had to go update their copy of MSVCRT.DLL to match. And if the Windows team wanted to fix a bug in MSVCRT.DLL, they had to make sure that the Visual C/C++ team made the corresponding change in their version.

This high degree of coördination became untenable, especially since it required the Windows team to do things like push a new version of MSVCRT.DLL to all downlevel platforms whenever a new version of Visual C/C++ came out. (Good luck doing this in the days before Windows Update!)

And sometimes these fixes caused compatibility problems. For example, I remember there was a fix for a Y2K problem which caused one application to crash because the fix altered the stack usage in such a way that exposed an uninitialized variable bug.

One serious problem with the MVSCRT.DLL "one runtime to rule them all" model is that multiple versions of Visual C++ would all use the same library, and keeping one DLL compatible with all versions of Visual C++ was a maintenance nightmare. For example, if a new C++ language feature required a change to the ostream class, you had to be careful to design your change so that the class was still binary-compatible with the older version of the class. This meant not changing the size of the class (because somebody may have derived from it) and not changing the offsets of any members, and being careful which virtual methods you call. This was in practice not done, and the result was that (for example) Windows 95 and Windows 98 both had DLLs called MSVCRT.DLL that were not compatible with each other.

And of course there was the problem of some application installer unwittingly overwriting the existing copy of MSVCRT.DLL with an older one, causing the entire operating system to stop working.

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. All newer versions of Visual C/C++ used specifically-numbered DLLs for their runtime libraries. (Giving different names to each version of the run-time library solves the problem of trying to make one DLL service multiple versions of clients, as well as addressing the accidental downgrade problem.)

Although MSVCRT.DLL has been an operating system DLL for a long time, and has been documented as off-limits to applications, there are still a lot of people who treat it as a C runtime delivery channel, and those programs create a lot of grief for the product team.

I remember one change that the runtime library folks made to MSVCRT.DLL that had to be backed out and revisited because they found an application that not only linked to MSVCRT.DLL instead of the runtime library the compiler intended, but also groveled into an internal array and manipulated private members. (I was one of the people who investigated this compatibility issue, but I was not the one who solved it.)

// Note: The issue has been simplified for expository purposes
struct SomethingInternal
{
    int widget;
    short widgetFlags;
    char widgetLevel;
    int needs_more_time;
};

SomethingInternal InternalArray[80];

The runtime library folks added a new member to the structure:

struct SomethingInternal
{
    int widget;
    short widgetFlags;
    char widgetLevel;
    int needs_more_time;
    int needs_more_cowbell;
};

This change increased the size of the Something­Internal structure, which in turn meant that when the application did

// Redeclare this internal structure in MSVCRT.DLL
// so we can poke the needs_more_time member to get more time.

struct SomethingInternal
{
    int widget;
    short widgetFlags;
    char widgetLevel;
    int needs_more_time;
};

extern SomethingInternal InternalArray[80];

...
    InternalArray[i].needs_more_time = 1;
...

it ended up poking the wrong byte because the structure size didn't match.

The runtime library folks had to go back and squeeze the cowbell flag into the structure in a way that didn't alter the size of the Something­Internal structure. I don't remember exactly what the fix was, but one way they could've done it was by squeezing the flag into the one byte of padding between widgetLevel and needs_more_time.

struct SomethingInternal
{
    int widget;
    short widgetFlags;
    char widgetLevel;
    char needs_more_cowbell;
    int needs_more_time;
};

Bonus chatter: The application had an easy time messing with the internal array because the source code to the C runtime library is included with the compiler, So much for "All these compatibility problems would go away if you published the source code." Publishing the source code makes it easier to introduce compatibility problems, because it lays bare all the internal undocumented behaviors. Instead of trying to reverse-engineer the runtime library, you can just sit down and read it, and if you want to do something sneaky, you can just copy the declaration of the internal array and party on the needs_more_time member.

Comments (113)
  1. Chris Crowther says:

    I continue to be amazed at the level of effort Microsoft go to in order to accommodate other people's stupid design and implementation choices.

  2. Anon says:

    I wish Microsoft would just start publishing compatibility issues and tell the developers to go do anatomically impossible things to themselves.

    Compatibility should be reserved for programs written properly, not poorly-written trash. It is this sort of thing which makes fruit-based operating systems seem more stable and better written, even when they aren't.

    [This program happens to be extremely popular among a certain category of users. There's a good chance you use it to keep your day running smoothly. Remember, the victim is not the developer of the bad program. It's the users of that program. "Microsoft makes an unnecessary change in order to break program X on purpose. That's because they hate people who use program X and want them to switch to Microsoft products." -Raymond]
  3. Medinoc says:

    The horror of MinGW piggybacking on MSVCRT instead of implementing its own Windows-compatible CRT is the reason one can't printf a long double in MinGW: MinGW uses 80-bit long doubles, while the CRT considers a long double the same as a double…

    @Anon: Even with a manifest explicitly specifying the execution level as asInvoker?

  4. Interested says:

    Could you tell us what kind of application it was that it warranted this amount of effort from you side? External or internal? Maybe some nuclear plant controlling SW (well, on second thought, hopefully not ;)

    [It's a language runtime. So this broke all programs written in that language. -Raymond]
  5. Ian Boyd says:

    Just to confuse things further.

    Starting with Windows Server 2003, there are some supported side-by-side assemblies (msdn.microsoft.com/…/aa376609.aspx):

    – WinHTTP 5.1

    – Microsoft Isolation Automation assemblies that enable the use of side-by-side assemblies with scripting.

    – Shell Common Controls version 6.0 (Comctl32.dll)

    – GDI Plus version 1.0 (GDIplus.dll)

    – Visual C++ Run-time Libraries version 6.0

    They don't document the names of the assemblies, but they are around on MSDN:

    – Microsoft.Windows.WinHTTP (msdn.microsoft.com/…/aa384082.aspx)

    – Microsoft.Windows.Common-Controls (nobody knows where it came from; lost to the sands of time)

    – Microsoft.Windows.GdiPlus (no idea where i found that)

    – vcrt 6? Who knows

    If you do need to ship another version of the Visual C++ libraries, their side-by-side assembly identifiers are also documented (msdn.microsoft.com/…/ms235624.aspx):

    – Microsoft.VC90.ATL (Active Template Library)

    – Microsoft.VC90.CRT (C Runtime Library)

    – Microsoft.VC90.OpenMP (OpenMP Library)

    (i omitted the names of four other assemblies; so that people are not tempted to use them)

  6. SimonRev says:

    @Anon — even today you will find questions on the official Visual C++ forums with programmers asking how they can link to MSVCRT.dll instead of the proper runtime for the current version of Visual C++.  Some get fairly irate when told they shouldn't do it.  It does seem like an obvious path if you don't want to use an installer to distribute your software.

  7. Adrian says:

    As I recall, DEC (Digital Equipment Corporation) chose the opposite route:  VAX/VMS was the distribution channel for all of the language runtimes.  This simplified life for the applications developers (presumably at the cost of dealing with DLL Hell).

    A friend who worked there told me that the OS engineers, in particular, thought this was a good idea, but they were afraid the product folks would try to undo the decision.  To make it harder to undo, they wrote bits of the OS in each of the languages that DEC had compilers for:  BLISS, C, FORTRAN, Pascal, etc.  With the OS dependent on the runtimes for all of the languages, it became much harder for others to argue that the OS shouldn't include the runtimes.

  8. Joker_vD says:

    "There's the mistake. It is perfectly reasonable for the C library to be a platform standard library. The same is not true of C++."

    Why is C so special? Why can't I have the Pascal, or the Haskell runtime library to be a platform standard library?

  9. John says:

    IIRC MinGW doesn't use MSVCRT.DLL because they don't know any better, but because linking with MSVCR71.DLL or MSVCR80.DLL or … and then publishing binary versions of MinGW (or GPL software compiled with MinGW) with the required "redistributable" DLLs would be a GPL violation.

    [Ah, the "There is no acceptable way for me to do what I want, so I'm FORCED to do it in an unacceptable manner" argument. This is like "I was forced to park in a fire lane because there were no parking spaces left". -Raymond]
  10. Maurits says:

    > fruit

    It's OK to say "Apple".

  11. Michael Kohne says:

    @Joker_vD: C++ requires too much knowledge of class layout at compile time, meaning you can't muck around behind the scenes in the library without breaking some apps. This goes even for private members of the class – the compiler accounts for those during class compilation, so if the actual binary doesn't match the header precisely, <kaboom>.

    To anyone high enough up at MS to make the call: We all understand you can't just not put the compatibility stuff in place (people then claim you broke things on purpose). But please start naming and shaming the companies that do absurd things like the example given above. It's not an optimal solution, but perhaps a bit of 'hey, look how much they suck' pressure would get at least some companies to clean up their acts.

    As to source code: Releasing the source works if everyone is working hard toward making a stable working environment for the user. If some people are instead trying to do whatever they have to in order to get the code out the door tomorrow, it doesn't help.

  12. Michael Kohne says:

    @John – on MinGW – is there any reason they can't write their own CRT? I imagine most of the libc should be useable (libc is LGPL), is there anything in MSVCRT that can't be replicated in a reasonable timeframe? Or is it just that no one's bothered to try?

  13. Jeff says:

    Off-topic question: why the umlaut on coördination?

  14. Anon says:

    @Medinoc

    Indeed, that will cause it to fail silently when AppCompat tries to force elevation.

  15. hagenp says:

    "keeping one DLL compatible with all versions of Visual C++ was a maintenance nightmare"

    That's what came to mind when I learned about the WDF team's approach to UMDF / KDMF distribution. "Wel will make sure newer versions are compatible with all existing drivers." Good Luck! :-)

  16. Joshua says:

    [Ah, the "There is no acceptable way for me to do what I want, so I'm FORCED to do it in an unacceptable manner" argument. This is like "I was forced to park in a fire lane because there were no parking spaces left". -Raymond]

    The tools that you disparage for doing unacceptable things have greater reputation than all of MS. We on this blog laugh with you at the results of people doing unacceptable things and wondering why disaster strikes, but this time the answer must be make an acceptable way or deal with the consequences of not doing so.

    GCC was ported to target Windows because a cross-compiler must exist, and at the time of the port MS compilers sucked badly. Cygwin exists because the POSIX subsystem failed of its promise.

    [As noted elsewhere, the correct solution is "Write and ship your own runtime library." Otherwise you may break at any future version of MSVCRT.DLL, since MSVCRT.DLL is not part of the API surface. -Raymond]
  17. Maurits says:

    > why the umlaut on coördination?

    So the two "o"s are pronounced individually rather than as a diphthong (like "cool"). Compare reënter.

    It is more usual to use a hyphen (re-enter) or just bleed the two words together and trust on the user being able to infer pronunciation from context (coordination) but that's not how Raymond rolls.

  18. hagenp says:

    Jeff: "ö" can be "o-umlaut" but also "o with a trema", indicating the vowel is pronounced unaltered and separate from the first one. So it is "co-ordination", and not "[cuurdinaishon]" or "[cohrdinaishon]" (sorry for not using IPA).

  19. SimonRev says:

    @Jeff:  From en.wikipedia.org/…/Diacritic:  The main use of diacritical marks in the Latin script is to change the sound-value of the letter to which they are added. Examples from English are the diaereses in naïve and Noël, which show that the vowel with the diaeresis mark is pronounced separately from the preceding vowel;

    Raymond often uses the diacritic marks on English words like that, even though they are archaic in modern English and almost never used anymore.  I think he explained why once, but I forget the exact reason.

    [Because that's how I learned the word. -Raymond]
  20. SimonRev says:

    Well, looks like I was a couple of minutes too slow on my answer :)

  21. Joshua says:

    [As noted elsewhere, the correct solution is "Write and ship your own runtime library." Otherwise you may break at any future version of MSVCRT.DLL, since MSVCRT.DLL is not part of the API surface. -Raymond]

    GCC targets MSVCRT.DLL as it was in NT4 when it was part of the API surface. Unless this is to be revoked ex post facto then nothing breaks.

    [It was not part of the API surface in NT4 either. It just happened to be there, just like today. -Raymond]
  22. Mike Dimmick says:

    @Mityador: "The 3rd party apps already depend (indirectly) on MSVCRT.DLL via other system DLLs (e.g. USER32.DLL, GDI32.DLL, COMCTL32.DLL etc.)."

    None of the DLLs you name import msvcrt.dll.

  23. Mordachai says:

    Ugh!  All of this angst and hand-wringing to justify or disparage the use of a system DLL!

    Do NOT use DLLs unless you MUST.  Link your freakin' application against all libraries it uses so that none of this is relevant.

    Obligatory preemptive anti-snark: buh, buh, in Windows 95 days it was too memory intensive!

    Are we seriously still in a memory crunch?  And seriously, with function-level linking, you pay only for what you use.

    Please!  Stop the insanity.  Link your freakin' apps fully.

  24. Snark says:

    [Please!  Stop the insanity.  Link your freakin' apps fully. -Steve Wolf]

    Yes, so heartbleed-like vulnerabilities can stay in forever!

  25. Mark Y says:

    You usually are pretty thorough about linking to previous relevant blog posts.  But this time you forgot "party on".

    [Temporal anomaly. I wrote this article first. Fixed, thanks. -Raymond]
  26. Mordachai says:

    @Snark – Vendors had to issue patches for heart-bleed.  No magical fix in some DLL works across the board.

    Having DLLs means every customer potentially has a different version of your software.  Good luck testing all of those…. and it's an infinitely expanding issue – since new DLLs means a growing test-issue – and you have to test combinations – making your problem an exponential growth one. :(

    DLLs only make sense where you want to supply hooks for dynamic behavior, you define it rigorously, and you work hard to ensure the interfaces are secure and cannot bust your runtime.  Every other places, use a freakin' static link so that your app as-test is the one your customers actually run.

  27. The Other John says:

    I second this "Why is C so special? Why can't I have the Pascal, or the Haskell runtime library to be a platform standard library?"

    Everyone likes to play high and mighty until it comes to their language of choice or their own mistakes. Typical. Play by the same rules or be a hypocrite, your choice. Windows is Not *nix.

  28. Joshua says:

    [It was not part of the API surface in NT4 either. It just happened to be there, just like today. -Raymond]

    Fair enough. In that case, dropping the copy of MSVCRT.DLL from MSVC 4.2 in System32 if it's not there should be safe.

  29. yuhong2 says:

    Nitpick: MSVCRT.DLL did not exist when Win95 was released, as VC 4.2 did not exist.

    And even the current MSVCRT.DLL still have to support old apps that linked to it for backward compatiblity.

  30. yuhong2 says:

    "especially since it required the Windows team to do things like push a new version of MSVCRT.DLL to all downlevel platforms whenever a new version of Visual C/C++ came out. "

    I think that was a myth, unless there was some important bug in a new version of MSVCRT that needed fixing (eg the Microsoft Libraries Update)

  31. kantos says:

    Of a cursory search of the main system DLLs (user32, advapi32, comctl32, kernel32, ntdll, gdi32)  it seems only advapi32 links directly to MSVCRT the rest seem to distill down to ntdll which last I checked was the interface to the kernel.

    Thus… if Advapi internalizes its version of the CRT (NTDLL has a LOT of exported CRT functions… so it might be able to use those instead) MS could just get rid of MSVCRT… and IMHO: SHOULD to prevent just this sort of craziness. The fact that this is even a debate is fairly stupid… it's MS' operating system, if they say not to link against it… DON'T.

  32. Joshua says:

    @kantos: If MS had not once said to link against it the debate would not exist.

  33. Bryan W says:

    @alegr1: Your premise on this is slightly incorrect: InstallShield elevates because it's manifested to be so in new versions and some features wouldn't work without elevation anyway in old versions.

    UAC-Aware applications are not subject to elevation based on name. E.g. you can manifest an installer named Setup.exe and it will install per-user no elevation if you do it right.

  34. GregM says:

    "Having DLLs means every customer potentially has a different version of your software.  Good luck testing all of those…. and it's an infinitely expanding issue – since new DLLs means a growing test-issue – and you have to test combinations – making your problem an exponential growth one. :("

    Building your application as a single monstrous EXE that statically links in the C and C++ Runtimes does not mean that you can avoid that.  There are video drivers, mouse drivers, network drivers, printer drivers, audio drivers, etc., that your application uses, and those involve DLLs too.  These aren't provided as part of the OS.

  35. Anon says:

    @Bryan W

    Try it. Add an as-invoker manifest to an application renamed "setup.exe" and see what happens. I have – it fails!

  36. ANon says:

    @Yuhong Bao

    "And even the current MSVCRT.DLL still have to support old apps that linked to it for backward compatiblity."

    Yes, that's the point of the article.

    NO apps should be linking to it, so it SHOULDN'T have to support anything for backwards-compatibility that isn't an OS component, and OS components would be updated alongside it!

  37. Joshua says:

    @panzi: en.wikipedia.org/…/Libiberty

    @Anon, @Brian W: An MSDN blog that I can no longer find via Google said to fix the problem by shimming the application specific non installer before shipping it. The situation apparently is the auto-detect is so stupid that if it doesn't carry the manifest for the latest windows version it will auto-elevate regardless of manifest. This creates a nasty problem for Cygwin's "patch.exe" which cannot be renamed. It's really too bad the auto-elevate is too stupid to figure out a console program named patch.exe should be ignored as that name is ancient now.

  38. Random832 says:

    "on MinGW – is there any reason they can't write their own CRT?"

    Because it'd defeat the purpose of the "Min" in their name. No idea why someone can't make a "MediumGW" that ships something like a copy of the reactos msvcrt though.

  39. mikeb says:

    MinGW is working to deal with the issues that might arise from using msvcrt.dll.  For example, newer versions of MinGW include their own `printf()` family of functions to deal with such things as the incompatible `long double` types and to support C99 format specs that aren't supported by MSVCRT.DLL.

  40. Ben Voigt [Visual C++ MVP] says:

    TL;DR version: %WINDIR%System32MSVCRT.DLL is the "Microsoft Windows OS C Language Standard Library".

    That the Windows OS C/C++ compiler shares a lot with the Microsoft C/C++ Optimizing Compiler shipped in Visual C++ (which in turn is shipped in Visual Studio) should not be confused with using the same runtime library.

  41. Tringi says:

    @Anon: You must be doing it wrong. I can successfully add manifest to file named setup.exe for which then no UAC pops up.

  42. Antonio 'Grijan' says:

    > Compatibility should be reserved for programs written properly, not poorly-written trash.

    Yes, that's how it *should* be in a perfect world. End users should not be punished for the mistakes of bad developers.

    But, unfortunately, we do not live in a perfect world, and, as Raymond has explained time after time, that would break many old line-of-business applications, many of which are more than two decades old and have lost the source code (or the tools needed to re-build it).

    As for the fruit-named approach, as a computer collector, I find infuriating not being able to run some programs from, for example, 1987 in a computer made in 1994… because of not keeping backwards compatibility (and yes, I own several computers from that company in my collection, spanning two decades). On the other hand, in Windows, you are almost warrantied being able to run a 1985 executable in Windows 8.1 (at least, in the 32-bit version).

  43. Anon says:

    @Jan Ringoš

    And as soon as a new Windows version (service pack, major release) is used, it will break.

  44. Anon says:

    @Antonio 'Grijan'

    I agree, the Microsoft approach is generally better, but not in the specific case of when Stability, Security, and/or Sanity are sacrificed at the altar of Compatibility.

    My chief example of this: You can't write a Setup application named *setup*.exe that doesn't require Admin access to a machine — Windows will elevate it and, if you force Windows to *not* elevate your Setup application, it will fail silently.

  45. Joshua says:

    [ For example, if a new C++ language feature required a change to the ostream class, you had to be careful to design your change so that the class was still binary-compatible with the older version of the class. ]

    There's the mistake. It is perfectly reasonable for the C library to be a platform standard library. The same is not true of C++.

    @Medinoc: Last I checked you get your choice but the default is MSVCRT. The driving force is "Why the *** should I ship a C standard library. This should be a platform library like all other platforms." Especially given MS's colossal screw-ups in the packing methods of MSVC*.DLL in the past.

  46. Joshua says:

    @Joker_vD: Because the OS is written in C and because the C library provides binary compatibility (almost*) for free and because the contents of the standard library change so slowly.

    * The only exceptions are the getc and putc macros which means the format of FILE * can't change; but then again why would it ever change?

  47. alegr1 says:

    @BrianW:

    [InstallShield elevates because it's manifested to be so in new versions and some features wouldn't work without elevation anyway in old versions.]

    Seriously? A glorified XML/table editor needs to run with administrator privileges?

  48. Mityador says:

    I second Joshua.

    Consider a non-Microsoft DLL as part of a non-Microsoft SDK for 3rd party application developers. For me, as an author of such SDK, it is a natural that you do not want your DLL to bloat apps of your customers. This implies:

    * You do not want to impose a dependency on MSVCRXXX.DLL (for whatever number XXX), because various customers use various MSVC versions.

    * You do not want to link C runtime statically. (consider the SDK may have many DLLs, you do not want plethora of C runtime instances in a process memory if it uses multiple of them).

    Furthermore consider you need to be compatible with all your customers, despite MSVC version they are using for building their apps. Hence you (as the SDK developer) have to be careful to not expose anything from C runtime on the SDK interface anyway. This involves things like:

    * C runtime resources allocated in the DLL (e.g. malloc()) must be released in the same DLL (free()). I.e. you cannot return malloc'ed memory and let the caller free it: you must free it in a function exported from your DLL.

    * Not using C/C++ runtime types (e.g. FILE*, std::string) in the public interface. I.e. no exported function takes that as a parameter and no function returns it.

    IMHO, sticking with MSVCRT.DLL (from the oldest Windows version supported by the SDK) is the most Right Thing (TM) for such use case. The 3rd party apps already depend (indirectly) on MSVCRT.DLL via other system DLLs (e.g. USER32.DLL, GDI32.DLL, COMCTL32.DLL etc.). So this way you do not bloat the app's memory space. You have just be compatible with the MSVCRT.DLL from the oldest Windows version supported by the SDK and not using the C++ stuff to avoid symbol mangling issues. (And of course: test, test and test once more, but that's a must-to-do for any SW development anyway, isn't it?)

    [How do you test on versions of Windows that don't exist yet? -Raymond]
  49. Mike Dimmick says:

    Nitpicking: MSVCRT.DLL doesn't actually contain ostream, or any C++ classes apart from the most basic runtime support. The legacy, non-templated (pre-STL) stream classes are in msvcirt.dll. Specific instantiations of std::basic_ostream (for char and unsigned short – VC6 has a typedef for wchar_t, not a real type) are in msvcp60.dll.

    These are all Windows components on Windows 7 – I think because Microsoft Management Console (for one) was originally written against MFC 6 for Windows 2000. Since anything actually written in VC6, using the Multithreaded DLL switch, will still be linking to these DLLs, they still have to be compatible with real VC6 code.

    @Joshua: Windows is not a *nix. The C runtime is not its lowest-level API. The Microsoft C runtime contains no calls to kernel mode. The lowest level it links to – in the VS6SP5 version I checked – is kernel32.dll, and that's true for all versions I have (everything from 6.0 to 12.0, barring 7.0) except for the latest version of 8.0 which for some reason is importing _getdrives from msvcrt.dll. If using the static multithreaded version of the runtime, you have to use _beginthread or _beginthreadex rather than Win32's CreateThread, so that the runtime is properly initialized for the new thread. Strictly speaking you should do it for the DLL version too, but the DLL version uses the callback to DllMain to initialize as a backstop.

    The current msvcrt.dll on Windows 7 SP1 has had its imports refactored so it now does take direct dependencies on kernelbase.dll, ntdll.dll and the API-MS-Win-XXX-L1-1-0 DLLs from the MinWin project.

    Windows CE (now called Windows Embedded Compact) does use a C runtime as its lowest-level API: coredll.dll has a mixture of C runtime APIs and Win32 APIs, with duplicated functions being removed. There seems no rhyme or reason to why a C API or a Win32 API was chosen in each case. This does lead to odd situations like the time() function not being available: you call GetSystemTime() and convert it yourself (that's a particularly horrible example as time.h *is* present, and it *does* declare time(), but the function is not present in any standard DLL). In the threading example, CreateThread is available but neither _beginthread or _beginthreadex is present. Each platform's coredll.dll is different, different static libraries and sometimes source code being linked into it at OS build time.

  50. alegr1 says:

    >You can't write a Setup application named *setup*.exe that doesn't require Admin access to a machine

    InstallShield IDE always causes an elevation prompt, because of the magic word in its name.

    @Ray:

    [Because that's how I learned the word. -Raymond]

    Are you pronouncing "what" and "why" as "hwat" and "hwy"?

    [I also pronounce "the" with long-E before a vowel, short-E before a consonant. Now get off my lawn! -Raymond]
  51. Crescens2k says:

    @Joshua:

    "If MS had not once said to link against it the debate would not exist."

    The problem with that is that the only time Microsoft had said to link against it for end user programs was before they started with the individual naming of the CRT libraries. After that they told end users to link against the appropriately named libraries, or if you don't want to ship around a CRT library, link against the static version of the CRT. After actually using VS from .NET onwards, Microsoft has always had their developer tools link against the numbered version of the CRT. XP was also about the time that MSVCRT became a system component.

    The only more recent cases where developers could link against the system CRT was for driver development iirc, but you had to get the DDK/WDK to link against it, it was only ever intended for driver related utilities to an extent, and they revoked that starting with Windows 8. What's more, before Windows 8, the driver environment was completely separate. There was no integration into VS like there is these days. So you had to deliberately get the DDK/WDK, ignore Microsoft in regards to what to link against the system CRT, start of a separate driver build environment command prompt or set up VS to use these paths and then build. There was no way to accidentally link against it. For Windows 8, they have started to ship a static library for the MSVCRT dependent driver utilities and I have a feeling that this was due to the misuse of the system CRT import library.

  52. yuhong2 says:

    "XP was also about the time that MSVCRT became a system component."

    With Win2000 actually.

  53. Crescens2k says:

    Right, was one out. Was a bit unsure which was why I used about.:3

  54. Harry Johnston says:

    I just wish that Visual Studio provided better support for writing code that doesn't use the C runtime library at all.  You can do it, but it isn't as straightforward as it could be – there are unexpected dependencies on it which require you to turn off some of the compiler's security features.  (I suppose it would be possible to pull out those particular parts of the C runtime and compile them directly into your program, but you'd lose compatibility with future versions of Visual Studio and there might be legal issues.)

    @mikeb: no matter what they do, there's no way to tell what new issues might be introduced by a future version of msvcrt.dll.  So if you want your application to be compatible with future versions of Windows, MinGW (in the default configuration) is not a good choice.

    @Joshua: note that the argument about backwards compatibility only applies to the 32-bit version.  The 64-bit version has never been advertised as being suitable for third-party developers to use.

  55. panzi says:

    @Medinoc I only once cross compiled a tiny shell program with MinGW so I'm not an expert on this, but I did use the option -liberty, which gave me the GNU (or C99?) printf. I think. I can't find *any* documentation on this, only Makefiles that use it. I don't even know how I know about this. Maybe some compiler error message told me about it?

  56. yuhong2 says:

    @Harry Johnston: Except that I think the original Platform SDK 64-bit compilers used it.

  57. ta.speot.is says:

    "If your program requires the Visual C/C++ Run-Time library, then your program needs to install the appropriate version. (There are redistributable packages you can include with your application.)"

    Too bad if you have Visual Studio 2010 SP1 because the bootstrap package for the Visual C++ runtime has the wrong ProductId (it's a GUID) and download URL. The README contains instructions only to fix the download URL, and they're half wrong anyway.

    If you don't update the ProductId at the same time the installer just assumes the runtime isn't installed and tries to install it again. And again. And again.

    connect.microsoft.com/…/msdn-forum-vcredist-x86-bootstrapper-package-xml-content-wrong

    I'm sure Microsoft handles thousands of GUIDs correctly every product release, but the above issue and the time someone changed the interface IDs for some ADO components really screwed me over.

    support.microsoft.com/…/2517589

  58. Minicrt 4 L-iz-ife says:

    When a fire lane is full of parked cars, is it still a fire lane? (Is Heartbleed the one where web servers divulge 64k in response to existential queries?)

    Windows: Not a Microsoft Visual C/C++ Run-Time delivery channel… OR THE GREATEST MICROSOFT VISUAL C/C++ RUN-TIME DELIVERY CHANNEL EVER?

  59. Cesar says:

    I believe mingw used msvcrt.dll because it was the Microsoft C compiler's C runtime, and they wanted to use the same runtime. Microsoft's decision to change the C runtime DLL filename with every new compiler release came later, and mingw just kept using the C runtime from the older compiler.

    It might seem strange today, but think about it: the mingw people came from Unix-style operating systems, where all compilers share a common C library. It was natural for them to do the same on Windows, even more when Microsoft itself was seen doing the same thing (including system components using that common C library); they would see no reason to gratuitously implement a separate, potentially incompatible (think about passing FILE pointers between modules) C runtime.

  60. Cesar says:

    And as to why doesn't mingw create its own C runtime now… I believe it's because of backwards compatibility. Programs compiled with mingw expect that the C runtime is the C runtime from that old Microsoft C compiler, or new versions of it. If that is changed now, a program compiled with the old mingw loading a plugin compiled with the new mingw (or vice versa) could break, since there would be two incompatible runtimes loaded (and the program could expect to be able to for instance allocate memory in the plugin and free it in the main program).

  61. Bryan W says:

    @anon: yep it works fine. Don't be surprised that using older versions and such doesn't work though. But yeah I've tested and seen it working fine.

    @alegr1: it's more complex than that. Some of the more esoteric likely less used features fail anymore. Can't really say if it's the way it is anymore but as long as com extraction exists you're probably looking at either some form of elevation or a portion of customers for whom it doesn't work.

    @joshua: on this blog of all things I would expect you to guess why there's more than one manifest version :-)

  62. immibis says:

    "Why is C so special? Why can't I have the Pascal, or the Haskell runtime library to be a platform standard library?"

    I third this. Unlike say Haskell, you can actually write fully functional C programs on Win32 without using the C standard library, because:

    * The standard library is written in C, which means it's possible to rewrite the parts you need.

    * The Win32 API is a C API, which means you don't need a standard library written in another language to call it.

    I've done this as an experiment (not in production code).

    The Haskell standard libraries could also be written in Haskell, using compiler extensions (because you need to define things like integers). I don't know anything about Pascal. For Python or Lua or JavaScript it might be difficult, but you could statically link with the interpreter and a module like ctypes.

  63. Michael Z says:

    Windows team could choose to rename its version to WINCRT.DLL and change Windows build system to use it (at least all low level components). Let Visual Studio own the MSVCRT.DLL. Very few people would link against an unknown new DLL.

  64. Jason says:

    I wonder, when you find such a bug (an application poking around in internal structures causing it to crash when the structures are changed), and it is apparently in a product that is so popular that you consider adding a workaround to your code, do you try to contact the vendor and ask them to fix it first? I mean it would be silly to do it for every single little program, but if it is a product of a huge company like Oracle, Adobe, SAP etc., it might be easier to just give them a heads up "you seem to depend on undocumented internals, we'll break your code in 6 months".

  65. voo says:

    @Jason The problem is that there are still millions of users out there running non-updated versions of the code. And most vendors wouldn't update their old products to fix such an issue but only the current one (hey great way to get people to upgrade, when windows n+1 breaks the application!)

  66. Eman says:

    So why not let people specify dependencies on MS-distributed components in a manifest embedded in the .exe so when the user double-clicks on it in Explorer, Explorer would parse that, check the needed components with the required versions are installed and if not, install them from Windows Update? Then that can be automatically filled in by Visual Studio when assembling the .exe. Or maybe Visual Studio could have an option to "export as installer for other people" that includes at least an installer for the runtime for people who don't have internet.

  67. Azarien says:

    @immibis: Free Pascal, for example, is entirely written in Pascal, so it is self-hosting. There's no msvcrt.dll in sight. Of course, it won't stop you from doing evil things like linking your program against msvcrt.dll and calling its functions, if that's your wish.

  68. acq says:

    msvcrt.dll was linked from Visual C 6 programs. Why should Microsoft want that programs compiled with Visual C become non-functional? What's so special in maintaining one compatible DLL? There are uncounted other DLL's that have to be maintained anyway.

    I really like msvcrt.dll existing in the system and I will keep producing the programs that depend on it as long as I can.

  69. Crescens2k says:

    @Cesar:

    The problem is that ever since the release of Visual Studio.NET in 2002, it has been made loud and clear that programmers mustn't use MSVCRT in applications. For the whole not seeing a reason to implement a separate CRT, well MSVCRT was only ever there originally as a way to make applications behave when it came to using MSVCRT. This was in response to the stability on Windows 95/98 where programs would overwrite MSVCRT that was in System/System32 and cause drivers to die or act weird because the version of MSVCRT was incompatible. After February 2002 when Visual Studio.NET was released, Microsoft has been quite clear that post VC98 compilers must not use MSVCRT for Windows software development*.

    After that point it was also obvious that they saw it mainly as a compatibility thing when they never updated the main entry points in the library to be more standards conformant and it also allowed them to cut down on things inside the library itself. Two things that I can refer to that help support this was that for the mingw usage of wcs* functions, there was a report on how they didn't work on Windows XP due to MSVCRT not containing those functions. Secondly, inside the CRT sources there are lots of cases where you see

    #ifndef _SYSCRT

           /*

        * Register __clean_type_info_names so that we clean up all the

        * type_info.names that are allocated

            */

       atexit(__clean_type_info_names);

    #endif  /* _SYSCRT */

    So not only is MSVCRT not guaranteed to contain everything, but it is also not guaranteed to work correctly in all cases. So while this could have been a point of contention back in time, now days it is silly to discuss it. Microsoft has been clear on what MSVCRT is there for.

  70. Erik F says:

    @acq: I will assume that you meant your comment to be humourous and just remind you that reasoning like that is why Windows has its 64-bit components in SYSTEM32 and its 32-bit ones in SYSWOW64.

  71. MSVCRT.DLL Enthusiast says:

    Are we allowed to use CRTDLL.DLL as an alternative to MSVCRT.DLL?

  72. Medinoc says:

    @Bryan W, Alegr1, Anon: I just tested asInvoker by building a simple program called TestSetup.exe (it just displayed a message box) with Visual Studio 2010 SP1 on Windows 7 from my UAC-enabled admin account. I got a weird hybrid result: asInvoker worked (I tested with CheckTokenMembership() with and without "run as administrator"). However, after my simple program exited (returning zero) when running non-elevated, I got a dialog box saying that maybe the install failed, and asked whether I wanted to run it again with some compatibility options enabled (and the option to run it again requires elevation).

    So Windows 7 still detected it as a setup program, but didn't prevent me from running it un-elevated.

  73. Medinoc says:

    discontinued in VS2010?

  74. Joshua says:

    [It may be best for you, because you externalized part of the cost of supporting future versions of Windows. Now it's Windows's job to support your app, rather than vice versa. -Raymond]

    MS's own pickle. VC6 links against it by default. support.microsoft.com/…/259403

    What's worse: not shipping MSVCRT.DLL or shipping the last redistributable version of what is now a "you shall not upgrade" system component?

    [The set of applications compiled with VC6 is relatively constant, not growing. Also, can you go talk to the people who say "Microsoft should tell these apps to screw off and not be held back with all this backward compatibility nonsense"? I can't really tell whose side everybody is on any more. -Raymond]
  75. Klimax says:

    "The set of applications compiled with VC6 is relatively constant, not growing. Also, can you go talk to the people who say "Microsoft should tell these apps to screw off and not be held back with all this backward compatibility nonsense"? I can't really tell whose side everybody is on any more. -Raymond"

    Easy. If it doesn't affect me or programs I use then screw it, if it does affect, then you MUST support it.

  76. Bryan W says:

    @medinoc: you have to include an extra manifest section for compatibility to eliminate that prompt. So you have the vista key but are missing the 7+ key :-) I can't recall exactly what you have to set up, but it's weird.

    @Raymond: the answer is everyone is on the side of what's most convenient for them at the moment. Obviously Microsoft should ship windows 9 no back compat edition and windows 9 full compat edition since that worked so well for ie7! /s

  77. Mark S says:

    > So much for "All these compatibility problems would go away if you published the source code." Publishing the source code makes it easier to introduce compatibility problems, because it lays bare all the internal undocumented behaviors. Instead of trying to reverse-engineer the runtime library, you can just sit down and read it, and if you want to do something sneaky, you can just copy the declaration of the internal array and party on the needs_more_time member.

    I guess that's a lesson the .NET team is about to learn.  Thanks to reflection you don't even need to copy the declaration of the array!

    visualstudio.uservoice.com/…/4083118-allow-developers-to-step-through-net-framework-so

  78. nobugz says:

    This is just a consequence of a broken expectation.  Because Windows actually *is* a delivery device for executable code.  It has been quite a while since I plugged in a USB device or hooked up a new printer, etcetera, and Windows did not automatically install the device driver for the device.

    Pretty strange that it is capable of delivering non-Microsoft files but can't do the same for its own.  The application manifest in VS2005+8 was a great opportunity to implement this.  That it didn't happen is surely a core reason it was discontinued in VS2010.  Great loss.

  79. Joshua says:

    [Also, can you go talk to the people who say "Microsoft should tell these apps to screw off and not be held back with all this backward compatibility nonsense"? I can't really tell whose side everybody is on any more. -Raymond]

    My position seems to be unique: A published API is forever. A published ABI is for as long as the platform lasts. He who depends on a bug deserves to be broken. He who depends on undocumented functions is asking for trouble.

    But even I cannot always escape doing something nasty because the work must get done and there's no good way to do it. I have to live with the fact I have to then fix it up with every version of Windows that comes out. Business cost of poor technology choices. "Supported" doesn't mean much when we can't even buy bugfixes.

  80. Mityador says:

    @Mike Dimmick: "None of the DLLs you name import msvcrt.dll."

    True. Mea culpa. But there are others, which do import it (for example UXTHEME.DLL — btw, imported by COMCTL32.DLL version 6).

    @Raymond: "How do you test on versions of Windows that don't exist yet? -Raymond"

    We don't as well as we would not if we link with other C runtime. Furthermore the SDK has its own docs, where we document supported system versions. So supporting future Windows versions is not contractual, and it also wouldn't even if we use other C runtime. Still, of course, we do our best to not have problems in the future. Furthermore I do believe Microsoft is sane company too: Although MSVCRT.DLL interface is not contractual, can you really imagine MS will remove it, rename it, or stop providing standard C functions in it? Arguably, if it really happens, Microsoft shall no more be Microsoft as this company is actually defined by the focus on the compatibility, as your own posts in this blog document so well. (Feel free to call me *** for relying on your work ;-)

    SW design is about trade-offs and in the use case discussed we evaluated this approach as best one, taking the risks into account. Believe me I would prefer if Microsoft provides better way for SDKs which do not want to exhibit the problems described in my previous comment.

    [It may be best for you, because you externalized part of the cost of supporting future versions of Windows. Now it's Windows's job to support your app, rather than vice versa. -Raymond]
  81. dasuxullebt says:

    > So much for "All these compatibility problems would go away if you published the source code." Publishing the source code makes it easier to introduce compatibility problems, because it lays bare all the internal undocumented behaviors.

    A well-known example is the Linux-Version of Skype, which used undocumented Features of ALSA, and required X11-extensions without fallbacks.

    The problem could go away if *everyone* published their source code, as you could quickly produce a patch. Anyway, as it is part of Microsoft's business model to fix the bugs of other people, maybe that could even be an advantage :3

  82. yuhong2 says:

    @MSVCRT.DLL Enthusiast: CRTDLL.DLL is even older (dates to NT 3.1 era I think).

  83. Neil says:

    @Harry Johnston I used to do this with toy Win16 apps, where it was easier because the Win16 API included more CRT-like functions than the Win32 API does. (By "toy" I mean that the icon was normally the largest part.)

  84. 640k says:

    If it's a compiler specific dll, the 64-bit version of msvcrt32.dll is obscene.

    @immibis:

    Windows is using the PASCAL calling convention for almost all APIs. Not the C calling convention.

    Thus Windows API surface is more tainted by PASCAL than by C.

    @Snark:

    "[Please!  Stop the insanity.  Link your freakin' apps fully. -Steve Wolf]

    Yes, so heartbleed-like vulnerabilities can stay in forever!"

    The first thing I do every time I create a new C/C++ project is to select static linking for Debug and Release.

    Not because I'm a unix zealot, but because distributing the runtime is a PITA, but more importantly, its

    installer extracts and leaves its "temporary" binary files in the root of the drive. This is such an ugly

    bug it makes me wanna cry.

  85. Boris says:

    Naturally, I understand if you learned to spell with a diaeresis (just as I learned to spell in the American way), but it's not like the Ö is just as easy to type. Presumably you're pressing the Windows logo key + Spacebar every time you need to type it, in order to switch to something like the German keyboard, and then the same in order to switch back. Since the right thing in this case, as defined by descriptive lexicography, is easier to do than the wrong thing, aren't you trying to climb out of the "Pit of Success"?

  86. Chris says:

    The more important question is, why do we need a needs_more_cowbell flag in the first place? Is it not always set to true?

  87. smf says:

    To solve this you need to add structure offset randomisation. Sure it will need compiler, linker, debugger and os changes. But lets see them figure out how to poke stuff then.

  88. MNGoldenEagle says:

    @Boris: The US International keyboard is a lot easier.  It turns " into a dead key such that " + o = ö.  The only downside is writing actual quotation marks or apostrophes, since to do that you have to type " + [space].

  89. @MNGoldenEagle says:

    For exactly this reason I dislike the US International layout, because the dead keys interfere with programming a lot. The X11 world has a much nicer variant called altgr-intl, which has no dead keys (ö is Right Alt + p, for example). I don't know if there's a way to use it in Windows.

  90. Boris says:

    MNGoldenEagle: I don't mind learning a Serbocroatian keyboard layout in order to ensure that my Č, Ć, Đ, Š and Ž retain their diacritics, but that's because it isn't acceptable to leave them out in any but the most casual of contexts (such as instant messaging or informal emails). In this case, though, I don't quite see how Raymond's managed to retain the habit over the years, unless the resulting text looks subjectively incorrect.

  91. Joker_vD says:

    @MNGoldenEagle: It's easier to remember that ö is Alt+Num0246, and Ö is Alt+Num0214. I mean, everybody already has to memorize that the em-dash is Alt+Num0151, and the en-dash is Alt+Num0150, so two more combinations is no big deal… right?

    [Even easier to remember is &ouml; -Raymond]
  92. Anon says:

    [It may be best for you, because you externalized part of the cost of supporting future versions of Windows. Now it's Windows's job to support your app, rather than vice versa. -Raymond]

    Actually, Microsoft chose to support these, and allow scope to creep, so Microsoft internalized the cost of supporting the external app.

    What's the business case for going to your boss and asking them to pay to maintain applications which Microsoft is currently maintaining for them at no cost?

  93. Maurits says:

    > ö

    Except commenters don't have the luxury of using HTML escape sequence in the comment box. (Though I suppose we could open a scratch HTML file.)

    [The original question was how I typed them. -Raymond]
  94. Maurits says:

    How amusing. I quoted "> ö" (which I expected to include a semicolon) and now my (Raymond-edited) text shows "> ö" (which includes an umlaut.) Looks like there's a bug in Telligent HTML encoding; either my original plaintext wasn't HTML-encoded correctly originally, or Raymond's editing tool didn't HTML-encode it correctly when he added his own HTML.

  95. Maurits says:

    Looks like it's the former.

    Let's try this again:

    > &ouml;

  96. Rick C says:

    @Boris, depending on the application, you can type Ctrl-: then O to get the O-with-diaresis.  This generalizes to most (Western-language) common accented letters:  Ctrl-~+n gives you n-with-a-tilde.  (I happen to not be on a Windows machine right now so I can't demonstrate because I don't feel like looking up the HTML entities.

  97. Rick C says:

    @Maurits:  well, now you broke it.  Are you happy?

  98. mh says:

    @Jason:

    "I wonder, when you find such a bug (an application poking around in internal structures causing it to crash when the structures are changed), and it is apparently in a product that is so popular that you consider adding a workaround to your code, do you try to contact the vendor and ask them to fix it first?"

    If it's what I think Raymond seems to be hinting it is, then it's not just one product; this has actually shipped in many many applications, some of which are smaller applications from vendors which may no longer exist.

  99. Maurits says:

    @Rick C: to get &ouml; to show up I had to type &amp;ouml;

  100. Joker_vD says:

    @Maurits: But what did you type to get &amp;ouml; ? Man, I hate quotations/escaping and especially, how many different schemes of those there are.

  101. Random User 29387 says:

    Minicrt 4 L-iz-ife: "When a fire lane is full of parked cars, is it still a fire lane?"

    As one gentleman's (jerk's) Corvette can attest, yes! The fire engine will unhesitatingly ram the cars out of the way and the city will bill the owners for the damage.

  102. Boris says:

    Ahem…

    "Games give you hand-eye coordination and spatial intelligence together with map-reading skills"

    "This gets even more complicated when the parent/child or owner/owned relationship crosses processes, because cross-process coordination is even harder than cross-thread coordination."

    "Since there is no coordination among the various applications, you're basically stuck playing a game of walls and ladders, hoping that your ladder is taller than everybody else's wall."

    "Like the adoption of a child, it's the sort of thing you should only be doing with the coordination of all three parties (the old parent, the new parent, and the child)."

    "Whenever there is a coordination problem, somebody says, 'Hey, let's create a process!'"

    "The effort required to fix the spelling was a bit more than usual, since the function was used by multiple teams, so there would have to be some coordination among the teams so everybody fixed their spelling at the same time."

    [Sometimes I'm lazy. You must be a lot of fun at parties. -Raymond]
  103. Anon says:

    @Random User 29387

    There is little more satisfying than knowing that firefighters and police will intentionally do as much damage as possible to a vehicle parked in a fire lane, except perhaps the knowledge that insurance won't pay for it.

  104. Engywuck says:

    then you have strange firefighters – we learned that we *had* to do as least damage as possible given the constraints that the fire had to be put out (so if there's a way around the vehicle that isn't too much longer and doesn't damage it you have to take it). Of course you take the registration number and they then get a fine of 65€ and 1 point in their registration. Plus they have to pay for any damage that occured because they were in the fire lane, costs for towing them away, etc. But you as firefighter have the obligation to cause as less damage as possible, including to vehicles of idiots.

  105. Gregory says:

    out of curiosity, why aren't the various C runtime versions delivered through Windows update instead of requiring each application to embed the redist installer?

  106. Gabe says:

    Gregory: Are you asking why Windows Update isn't a Microsoft Visual C/C++ Run-Time delivery channel?

  107. Gregory says:

    Gabe: in other words, yes. It's so central in the Windows ecosystem I'm surprised developers' life isn't made easier (for those who link dynamically against the runtime). Same question could apply to DirectX RunTime. But maybe one would argue the list of runtimes would become so long it's not a sustainable position?

  108. Random User 29387 says:

    Engywuck: I'm not 100% certain but I think the guy was not only in the lane, but also obstructing meaningful access to the fire plug. Either way, I'm satisfied with the explanation that different localities have different laws RE: liability of the fire dept, etc.

  109. Engywuck says:

    we were especially told "don't do like in the movie when a car parks afront of a hydrant. If you have time to smash the windows you have time to put the firehous over or under the car"

    but ontopic: wsus delivers already .NET in the "features" section, other libraries could easily go there, too. Sure, .NET is needed for quite a few internal windows things instead of "only" third-party programs, but I wouldn't object of them going there :-)

  110. Gabe says:

    Engywuck: If a hose has too much of a bend or kink, it can decrease the flow too much. I think that typically they put the hose through the windows because that allows it to be straighter than going over, under, or around. I did recently see a photo where they had broken the windows to pass the hose through, only to find that there was still too much of a bend, and they had to pick up the car and move it a few inches over to get full pressure.

    But on topic: Gregory, I'm pretty sure that most would argue that Windows Update shouldn't be a delivery channel for anything besides updates. If you have some VC runtime that's been installed by a 3rd-party app, then WU should probably update it. I don't see why WU should be installing arbitrary software, though.

  111. Anon says:

    @Gabe

    Microsoft Visual C++ Redistributables are, typically, "updates." They'd just fall under "other software" in Microsoft Update.

    A better question is "Why doesn't the redistributable installer simply come with all available versions of the redist, and why doesn't the new redist release with stripped-down versions of the old redist, to save space?"

  112. Joshua says:

    Did they fix the C stdlib to always work when the DLLs are copied beside the EXE yet?

  113. GregM says:

    "I did recently see a photo where they had broken the windows to pass the hose through, only to find that there was still too much of a bend, and they had to pick up the car and move it a few inches over to get full pressure."

    Yes, that exact thing happened in Boston last week.  I heard third-hand that the car was only 3 days old.

Comments are closed.