Linking error when building without CRT, memcpy and memset intrinsic functions

Knox picture Knox · Jan 27, 2014 · Viewed 11.7k times · Source

I'm trying to build an application as tiny as possible, and in doing so I'm trying to avoid use of the CRT by using Win API calls instead of standard C/C++ calls. Unfortunately, I'm still getting a single linker error:

Error   2   error LNK2001: unresolved external symbol _memcpy

I don't call memcpy anywhere in my code, so I presume one of the Windows functions is calling it. Turning on intrinsic functions gives an unresolved symbol _memset, which I don't use either. From my understanding, both memcpy and memset should be included with intrinsic functions enabled. Since my code is too long to post, here are the Win API calls in my program:

  • lstrcpy
  • wsprintf
  • CopyMemory - the error switches to _memset when I comment this out
  • OpenFileMapping
  • MapViewOfFile
  • CreateFileMapping

My questions:

  • Why aren't the intrinsic functions being included if I have /Oi declared?
  • Do I need to declare memset and memcpy on my own?
    • If so, how do I do so without Visual Studio complaining of redefinition of intrinsic functions?

Answer

Mahmoud Al-Qudsi picture Mahmoud Al-Qudsi · Oct 13, 2017

/Oi is not documented as necessarily inserting all intrinsics where possible, instead it merely gives the compiler the option of doing so. I haven't been able to figure out what logic MSVC uses to reach its final conclusion, but some factors include the project mode (it's far more likely to inject the intrinsics in RELEASE as compared to DEBUG) and the length of your functions.

Recent versions of Visual Studio really have integrated MSVCRT dependencies into the compiler and it's become increasingly harder to generate code that does not depend on the standard C runtime.

The standard way of working around these issues (though extremely looked down upon by Microsoft) is to link against the system copy of MSVCRT.dll, which ships in some form or the other with all versions of Windows. So long as you are using standard C functions like memset you can soundly ignore Microsoft's piercing glares of disapproval and link away to your heart's content, but don't try to use it for more complicated functions and APIs provided by the CRT.

To link against msvcrt.dll you'll need to either use LoadLibrary and co or else use a pre-generated msvcrt.lib (Microsoft purposely does not provide one) to tell MSVC which functions are available in the system MSCRT.dll


Update: we now publish precreated mscvrt.lib files for statically linking against the CRT (at your own risk!) for x86 and x64 platforms: https://github.com/neosmart/msvcrt.lib