10

This is part of a series of at least two closely related, but distinct questions. I hope I'm doing the right thing by asking them separately.

I'm trying to get my Visual C++ 2008 app to work without the C Runtime Library. It's a Win32 GUI app without MFC or other fancy stuff, just plain Windows API.

So I set Project Properties -> Configuration -> C/C++ -> Advanced -> Omit Default Library Names to Yes (compiler flag /Zl) and rebuilt. Let's pretend I have written a suitable entry point function, which is the subject of my other question.

I get two linker errors; they are probably related. The linker complains about unresolved external symbols __fltused and _memcpy in foobar.obj. Needless to say, I use neither explicitly in my program, but I do use memcpy somewhere in foobar.cpp. (I would have used CopyMemory but that turns out to be #defined to be identical to memcpy...)

(I thought I could get rid of the memcpy problem by using a compiler intrinsic, like #pragma intrinsic(memcpy), but this makes no difference.)

If I look at the preprocessor output (adding /P to the compiler command line), I see no references to either __fltused or _memcpy in foobar.i.

So, my question is: Where do these linker errors come from, and how do I resolve them?

Community
  • 1
  • 1
Thomas
  • 174,939
  • 50
  • 355
  • 478

2 Answers2

16

__fltused implies you are using or have at least declared some floats or doubles. The compiler injects this 'useless' symbol to cause a floating support .obj to get loaded from the crt. You can get around this by simply declaring a symbol with the name

#ifdef __cplusplus
extern "C" {
#endif
int _fltused=0; // it should be a single underscore since the double one is the mangled name
#ifdef __cplusplus
}
#endif

WRT _memcpy - memcpy is a __cdecl function, and all cdecl functions get an automatic _ as part of their decoration. so, when you say "__cdecl memcpy" - the compiler & linker go looking for a symbol called '_memcpy'. Intrinsic functions - even explicitly requested - can still be imported if the build settings have debug settings that contra-indicate intrinsics. So you are going to need to implement your own memcpy and related functions at some point anyway.

ilw
  • 2,499
  • 5
  • 30
  • 54
Chris Becke
  • 34,244
  • 12
  • 79
  • 148
  • Thanks for the quick answer! Unfortunately, the `__fltused` trick seems to do nothing for me. I put `int __fltused = 0;` at the top of `foobar.cpp`; static or non-static doesn't make a difference either. – Thomas Oct 17 '09 at 21:28
  • Also, I'm fairly sure I'm not using any floats or doubles anywhere. My source tree doesn't contain these words. – Thomas Oct 17 '09 at 21:42
  • ah, sorry. forgot about the extern "C" part. – Chris Becke Oct 18 '09 at 12:53
  • 2
    it should be a single underscore since the double one is the mangled name – paulm Jul 10 '13 at 19:11
  • As a more compact alternative to the linkage specifier used in the answer, you can use `EXTERN_C` (declared in ``) instead: `EXTERN_C int _fltused = 0;`. There's no need to distinguish based on the `__cplusplus` preprocessor symbol, as that is already taken care of with the `EXTERN_C` macro. – IInspectable Nov 29 '13 at 11:32
2

I recommend setting the "generate assembly listing" (or some such) compiler option for foobar.cpp once, and then inspecting the assembler code. This should really tell you where these symbols are used.

Martin v. Löwis
  • 124,830
  • 17
  • 198
  • 235
  • I'm not exactly an x86 assembler guru. But if I can get the tools figured out, I might give this a try tomorrow. – Thomas Oct 17 '09 at 21:29