15

I've tried Googleing this but I could not find a solution. I am trying to learn some basic C++. I wrote a simple hello world:

#include <stdio.h>
int main()
{
    printf("hello, world\n");
    return 0;
}

It compiled perfectly and everything! Great I thought, so I loaded up my virtual machine with XP and no service packs installed, then tried to run it. It told me I needed the MSVCR dll. Is there any way I can completely remove this dependency? I don't want to stuff the program with the dll. I want it to be gone, completely. Is it possible to make and run a program that will run in XP and up? Thanks.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
dorey
  • 151
  • 1
  • 1
  • 3

3 Answers3

21

It is technically possible to remove this dependency in C, but I'm not sure it is even possible in C++. And in either case, I would not recommend it. You lose a lot of stuff that the CRT does for you behind the scenes, most of which you don't want to have to reinvent yourself in an inferior fashion. For starters, it's the runtime library that actually calls your main function as well as calling the constructors and destructors for global and static C++ objects.

The best and simplest solution is probably to change how your application links to the runtime libraries. You have two different options: dynamically and statically. Dynamic linking is more memory-efficient and means that your application will take advantage of any bug fixes that are made to the library. It relies on the runtime DLL being present in order for your app to start. Static linking actually embeds the runtime library code into your application during the link phase of the build. This means that you can run without distributing the DLL, but there are important caveats.

For simple apps, it's unlikely that these caveats are relevant. Change the link style in use in your project's options:

  1. Right-click on your project name in the Solution Explorer.
  2. Expand the "C/C++" option in the left-hand treeview, and select the "Code Generation" item.
  3. In the "Runtime Library" property combobox, choose one of the "Multi-threaded" options.
    Debug builds should use "Multi-threaded Debug", while Release builds should use "Multi-threaded".

Do note that since you're using VS 2010, you can still choose to dynamically link to the runtime and gain all of the advantages of doing so without having to run the CRT installer on the target machines. All you need is the redistributable DLL(s) placed into the same folder as your application's executable. This makes deploying (and even testing) very simple and straightforward. You'll find these libraries as part of your Visual Studio installation:

\Program Files\Visual Studio x.0\VC\redist\

And of course, the debug versions of the CRT are never redistributable. Since you should not distribute debug versions of your application, this is not a problem. Make sure that you've compiled a "Release" build (using the drop-down combobox in the top toolbar), for which you will require only the redistributable libraries found in the above directory.


Can't I use the runtime that comes with XP?

There is no C runtime for you to use that comes with any version of Windows. Windows itself indeed depends on a C runtime library, but it deploys a private version of that library for its own use. Applications are not intended to link to it or make use of it in any way. You're on your own for deploying all necessary dependencies, and as you've noticed, you cannot assume that the target machines will already have the correct version(s) installed.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • So I am guessing this wont allow it to run on Windows XP without the newest runtime being installed. I'll try this, thanks. – dorey Jan 29 '12 at 11:24
  • Avoid mentioning the CLR, it isn't relevant here. And do point out that the deployment suggestion can only work for VS2010, previous versions use the Windows side-by-side cache. – Hans Passant Jan 29 '12 at 17:02
  • @Hans: Whoops! That was a typo, I meant the CRT. And thanks for pointing that out about VS 2010. – Cody Gray - on strike Jan 30 '12 at 00:00
5

You can link the MS runtime statically, Project Options -> C/C++ -> Code Generation -> Multithreaded (or Multithreaded Debug for debugging configuration). No DLL should be needed then.

Karel Petranek
  • 15,005
  • 4
  • 44
  • 68
  • I don't want to link them. I want to avoid them if possible. – dorey Jan 29 '12 at 11:17
  • 3
    You cannot avoid C++ runtime. It's the very thing that calls your `main()` function. – Sim Jan 29 '12 at 11:19
  • Can't I use the runtime that comes with XP? – dorey Jan 29 '12 at 11:19
  • @Sim: You CAN avoid C++ runtime, but it is not for the faint-hearted and definitely not for newbies. See http://wcrt.sourceforge.net/ for an example implementation (that has few bugs). In long term - it isn't worth the hassle. – SigTerm Jan 29 '12 at 11:32
  • @SigTerm: But...what exactly is the advantage of replacing Microsoft's CRT with an inferior third-party runtime library? You can statically link either one, and the linker is only going to link in the functions that you're using. It's quite irrelevant whether the library itself is "small" when you're statically linking. – Cody Gray - on strike Jan 29 '12 at 11:44
  • 2
    @Cody Gray: compiled executable size and no dependencies. `int main(){return 0;}` will produce 16kB executable that can be compressed into 2..6kB, and the only dependency is msvcrt.dll, which is system component. You can get rid of even that dependency and make your own stripped-down crt (relying on system function like GlobalAlloc or VirtualAlloc and using _tmaincrtstartup) which will be even smaller, but in this case it'll get much more compilcated. Of course, all those tricks are only useful if you have very unique requirements for your app (demoscene contests with size limit, perhaps?). – SigTerm Jan 29 '12 at 12:14
  • @SigTerm: I mentioned both of those things already. Static linking only links in those bits of code that you actually use. If you don't use it, it doesn't get linked in. Therefore, the entire size of the library is irrelevant if you're only using a small part of it. There are also no dependencies if you statically link. And yes, `msvcrt.dll` *is* a system component. "System" meaning that your app should not use it because it's reserved for use by the system. Yes, a very simple application is somewhere around 10k bytes, but it doesn't scale linearly with complexity. – Cody Gray - on strike Jan 29 '12 at 12:17
  • @Cody Gray: I'm not saying that it is a good idea to get rid of CRT, I'm saying it can be done and wcrt was one way to approach the problem. There is very small number of scenarios when such tricks are useful. – SigTerm Jan 29 '12 at 12:24
  • 2
    @Cody msvcrt.dll is the MSVC6 runtime and is shipped with Windows starting from Win2k. It's perfectly fine to use. Saying that you should not link to DLLs supplied by the system is odd. Are you proposing that we stop linking to user32.dll et al? – David Heffernan Jan 29 '12 at 14:25
  • 1
    @David: It is not the MSVC6 runtime, it just has the same name. Microsoft has been actually been updating that runtime library for the Windows system components, adding some of the new features that are otherwise deployed under the versioned names. I can't recall exactly where I read it, but I have it on relatively credible authority that this library is intended to be private for Windows internal use, and not available for use by applications. The theory is at least supported by the fact that the .lib files for it are not made public. Linking to the private CRT is different from user32.dll. – Cody Gray - on strike Jan 30 '12 at 00:06
  • 1
    The best link I can find in support of my claim is here: [C Run-Time Libraries](http://msdn.microsoft.com/en-us/library/abx4dbyh.aspx), which says *"The msvcrt.dll is now a "known DLL," meaning that it is a system component owned and built by Windows. It is intended for future use only by system-level components."* All of this comes from the problems encountered with sharing a CRT across apps and the OS. You *can* link to this DLL, but it's not supported and not recommended. The system CRT is not tested or documented for general use; security updates can make your app fall on its face. – Cody Gray - on strike Jan 30 '12 at 00:19
  • @cody it was added as a windows component to deal with vendors who forgot to ship it as a dependency to their msvc6 apps in win95 times. It is the msvc6 runtime. – David Heffernan Jan 30 '12 at 07:21
  • 1
    @David: That's my point. What you're saying is true back in the Windows 95 times, but not anymore. Many of the Windows components have a dependency on msvcrt.dll, but they're obviously not using the old VC6 runtime because they wouldn't pass the security reviews. That DLL has been silently updated while retaining the same name to include new features, like secure string functions. It's not intended for use by app vendors. [Not that that's ever stopped people before](http://blogs.msdn.com/b/oldnewthing/archive/2008/01/11/7065021.aspx). – Cody Gray - on strike Jan 30 '12 at 07:46
  • @cody adding new functionality does mean the old interface has to be broken. Why can't it be msvc6 with extra bits added on? – David Heffernan Jan 30 '12 at 07:47
  • @DavidHeffernan: If you start with the msvc6, and then change it so much that code expecting it to act like msvc6 crashes, does it still count as the msvc6? – Mooing Duck Dec 01 '14 at 20:02
  • @Mooing I don't think that is what has happened – David Heffernan Dec 01 '14 at 20:05
3

you can remove the annoying run-time library, do this:
project properties > linker > input > ignore all default libraries> yes

this will give you quiet a few issues you need to deal with, for example, floating point numbers won't work, stack memory is very small (about 3k), there's no built in help against buffer overflows and such, and you can't use the standard library without copy pasting it in your project.

this will also decrease the size of the .exe nearly equivalent to as if it was hand made in assembly.