| whats problem with this code? msvs2005 |
|
| Author |
Message |
Av0id

|
Posted: Visual C++ Language, whats problem with this code? msvs2005 |
Top |
hello, it's my first post here, i have little problem, i'am trying to build minimal executable, but i can't, the main problem is 'unresolved external symbol _memcpy'
main project options is /NODEFAULTLIB, enabled intrinsic-functions and changed entry-point to WinMainA
here it my simple code which reproduce error:
#include <windows.h>
// Constants
struct _TEST { char test1[256]; char *test2; int test3; };
// Main code
void _test(_TEST *tst) { ZeroMemory(tst,sizeof(_TEST)); tst->test3=666; }
int __stdcall WinMainA() { _TEST mmm;
_test(&mmm); ExitProcess(mmm.test3); }
ps. this code successfully compiled on msvs2002-2003, please, help me to solve this, thanks
Visual C++7
|
| |
|
| |
 |
Mike Danes

|
Posted: Visual C++ Language, whats problem with this code? msvs2005 |
Top |
Are you talking about memcpy or memset ZeroMemory is a macro that leads to memset so its no wonder what this code needs memset. In addition enabling inrinsic functions is only a hint to the compiler to use them, the compiler may chose to not use intrinsics.
You have 2 options:
- Provide your own memset function. I got a 8 kb exe using a basic memset.
- Don't use NODEFAULTLIB but link to the static version of CRT. This allows the compiler to use the memset from CRT and since you don' use the entrypoint from CRT the rest of the CRT will not be linked in. I got a 13.5 kb exe which is still quite small.
|
| |
|
| |
 |
Holger Grund

|
Posted: Visual C++ Language, whats problem with this code? msvs2005 |
Top |
I'm not sure what exactly you're trying to achive, but in addition to what Mike said, you have a couple of options to reduce size of your executable:
1) Don't use memset, just use a parameterless functional-notation cast expression:
*tst = _TEST();
2) Don't use /Zl or /NODEFAULTLIB but bypass startup and cleanup. Of course, you must be very careful to avoid things that require CRT initialization or cleanup. E.g. just link with /entry WinMain. This should reduce the EXE size quite significantly, but of course, you don't get any automatic initialization/destructions of globals, local statics, handling exceptions escaping from main, FP initialization, /GS checks and a gazillion of other things ...
-hg
|
| |
|
| |
 |
Mike Danes

|
Posted: Visual C++ Language, whats problem with this code? msvs2005 |
Top |
"1) Don't use memset, just use a parameterless functional-notation cast expression:
*tst = _TEST();"
And how do you think the compiler will zero it out, especially given the size of the structure 
|
| |
|
| |
 |
Holger Grund

|
Posted: Visual C++ Language, whats problem with this code? msvs2005 |
Top |
Well, the code generators I've worked on (one of them trying to be highly compatible to VC on the ABI level while heavily optimized for performance for their own set of processors) used different intrinsics for compiler-generated initialization. Oc, VC doesn't ship with a stripped down version with just the compiler support code but other compilers do.
But that code, also has the additional benefit of signaling required alignment to the codegen, which allows it use just a plain rep stosd without having to account for additional alignment on either side. While VC's optimization isn't really strong at the microlevel it's probably still smart enough to figure out that an inlined rep stosd is a much better choice than calling a plain dumb memset here.
I don't quite get your argument about the size of the structure. It certainly is large enough to warrant using a loop-construct and certainly too small for vectorized execution to amortize set up costs.
So, in conclusion, I actually believe it does make a difference for a decent codegen (and I'd even bet VC 7.1+ would be good enough here, too). But then, I don't have access to a copy right now.
-hg
|
| |
|
| |
 |
Brian Kramer

|
Posted: Visual C++ Language, whats problem with this code? msvs2005 |
Top |
I did a quick test with Holger's code. The compiler generates a memset to construct the temporary, followed by a rep movs instruction to fill the destination *tst. Here's a variation that only uses rep movs. The static variable lands in memory that is assumed to be initialized to zero by the compiler. (Remove static and you get code similar to Holger's).
void _test(_TEST *tst) { static _TEST empty = {}; *tst = empty; tst->test3=666; }
|
| |
|
| |
 |
Mike Danes

|
Posted: Visual C++ Language, whats problem with this code? msvs2005 |
Top |
" which allows it use just a plain rep stosd without having to account for additional alignment on either side"
I thought so too a while ago but it does not seem to happen. Whatever optimizations flags I have tried the compiler keeps using memset.
"I don't quite get your argument about the size of the structure. It certainly is large enough to warrant using a loop-construct and certainly too for vectorized execution to amortize set up costs."
Well, I see you got my point. If it weren't for the char array in that struct the compiler would have used something along these lines
xor eax, eax
mov [ebp-4], eax
mov [ebp-8], eax
instead of calling memset.
|
| |
|
| |
 |
Holger Grund

|
Posted: Visual C++ Language, whats problem with this code? msvs2005 |
Top |
I don't have a VC 8 here, but what you say sounds like a bug to me (I guess, it's obvious that we're taking about compiling things with optimizations enabled). But I can see how VC 7.1 isn't any smarter. It does a rep stosd into a temporary followed a rep movsd. Maybe a placement new would do. But well, that's really embarassing.
-hg
|
| |
|
| |
 |
Av0id

|
Posted: Visual C++ Language, whats problem with this code? msvs2005 |
Top |
sorry, it's my typo the
problem is in '_memset', what i try to achieve i'm trying to get rid
of CRT and default libs, that's all
in vs2003 ZeroMemory
(memset) in same project compiled to 'rep stosx' without CRT and
additional lib's (without unresolved external symbols)
and
another thing i noticed, when i trying to compile this, it compiles
without error's, but this code doesn't generate 'rep stosx':
struct _TEST { //char test1[256]; char *test2; int test3; };
// Main code
void _test(_TEST *tst) { ZeroMemory(tst,sizeof(_TEST)); tst->test3=666; }
ps.
it's possible to redefine intrinsic function (_memset for example) or
it's better to redefine ZeroMemory in older VS i can redefine intrinsic functiondo it, but not in
2005
thanks for help
|
| |
|
| |
 |
Mike Danes

|
Posted: Visual C++ Language, whats problem with this code? msvs2005 |
Top |
"in vs2003 ZeroMemory (memset) in same project compiled to 'rep stosx' without CRT and additional lib's "
You were lucky probably. I had a similar problem when using VS2003.
"and another thing i noticed, when i trying to compile this, it compiles without error's, but this code doesn't generate 'rep stosx':"
Yes, as I already stated in another post if the array is not there then the compiler just zero out a register and simply writes that register value to test2 and test3 members.
"ps. it's possible to redefine intrinsic function (_memset for example) or it's better to redefine ZeroMemory in older VS i can redefine intrinsic functiondo it, but not in 2005"
You can redefine ZeroMemory (it's a macro) but keep in mind that if the compiler needs to zero out some memory somewhere it will try to use memset, not ZeroMemory. As for redefining the intrinsic function I don't know if it's possible. After all it's not even a function. It's some code that is generated by the compiler and inlined in your function.
"i'm trying to get rid of CRT and default libs, that's all"
I just hope you have a good reason for this 
|
| |
|
| |
 |
Av0id

|
Posted: Visual C++ Language, whats problem with this code? msvs2005 |
Top |
ok, i solved my problem with this code:
#pragma function(memset)
extern "C" void * __cdecl memset(void * const s, int c, size_t n) { unsigned char * const p = reinterpret_cast<unsigned char*>(s); for ( unsigned i = 0; i != n; ++i ) p = static_cast<unsigned char>(c); return s; }
thanks to everyone for help
|
| |
|
| |
 |
Brian Kramer

|
Posted: Visual C++ Language, whats problem with this code? msvs2005 |
Top |
Mike Danes wrote: | |
"i'm trying to get rid of CRT and default libs, that's all"
I just hope you have a good reason for this 
|
|
I'm also curious why this is a requirement. Is this for an embedded device where every byte counts
The longer you develop against VS2005, the more you may uncover more compiler dependencies against the CRT. Developing sans the CRT was never really a requirement in Visual Studio, so you're pursuing unsupported scenarios.
Brian
|
| |
|
| |
 |
Mike Danes

|
Posted: Visual C++ Language, whats problem with this code? msvs2005 |
Top |
" the more you may uncover more compiler dependencies against the CRT"
No, it's not that bad . That if you stay away from various C++ "advanced" features like exceptions, RTTI, static storage objects that have constructors and/or destructors etc. Keep in mind that the Windows kernel & drivers are compiled with the same compiler but there is no trace of msvcrt in kernel space, just some self contained functions like wcscpy, wcslen, atoi etc. that are exported from the kernel executable itself.
|
| |
|
| |
 |
Brian Kramer

|
Posted: Visual C++ Language, whats problem with this code? msvs2005 |
Top |
We're on the same page. I think the list you give, along with the "etc," is reason enough to not care about eliminating the CRT dependency. ATL had a "minimal CRT dependency" to help on ActiveX downloads, but other than that I'm generally against doing hacks such as above for an artificial requirement. Or is the requirement legitimate
|
| |
|
| |
 |
| |
|