Building Visual C++ app that doesn't use CRT functions still references some
Asked Answered
R

2

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?

Rrhagia answered 17/10, 2009 at 21:0 Comment(1)
Ah... must've lost that somehow whilst splitting this thing into two. Re-added it, thanks!Rrhagia
O
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.

Ormazd answered 17/10, 2009 at 21:10 Comment(5)
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.Rrhagia
Also, I'm fairly sure I'm not using any floats or doubles anywhere. My source tree doesn't contain these words.Rrhagia
ah, sorry. forgot about the extern "C" part.Ormazd
it should be a single underscore since the double one is the mangled nameIridescence
As a more compact alternative to the linkage specifier used in the answer, you can use EXTERN_C (declared in <winnt.h>) 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.Reticular
I
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.

Inventory answered 17/10, 2009 at 21:8 Comment(1)
I'm not exactly an x86 assembler guru. But if I can get the tools figured out, I might give this a try tomorrow.Rrhagia

© 2022 - 2024 — McMap. All rights reserved.