Sign in to follow this  
trevaaar

Difference between some Win32 and C standard library functions

Recommended Posts

I noticed that there are some Win32 API functions that appear to do exactly the same thing as some C standard library functions (wsprintf instead of sprintf, lstrlen instead of strlen, MoveMemory instead of memmove, etc.) and I'm wondering if any of you know what the difference is (performance for example) and why I should use one or the other (I'm not worried at all about portability because my apps use other Windows-only stuff like DirectX already).

Share this post


Link to post
Share on other sites
lstrlen and wsprintf are not exactly the same as strlen and sprintf.

lstrlen is a special implementation of strlen which operates on TCHARs rather than chars. A TCHAR is defined to be either a normal character (char) or a wide character (short) depending on whether you're using unicode or not.

wsprintf is very similar to sprintf - but the format specifiers are subtly different, since it's intended for use primarily with wide characters.

I'm not sure what the difference between memmove and MoveMemory is - if there is one.

Share this post


Link to post
Share on other sites
From what I can tell, there is a normal and wide character implementation of all the Win32 string functions (for example, wsprintfA or wsprintfW get mapped to wsprintf depending on whether UNICODE is defined, similar to _tsprintf). I'm just wondering what they're there for and if there's any reason to use either Win32 or C standard library other other than portability.

Share this post


Link to post
Share on other sites
The Windows functions that appear to be near-duplicates of C library functions are there because in the earliest days of Windows developement (i.e. back when Windows ran on 8088's) every byte counted and they didn't want to take the hit of including the C runtime. That sort of mentality still exists today although the reasons have changed - now people argue that they don't want to take the dependency and either have to ship another dll or increase the size of thier binary. Lastly you have to remember that although the Windows API is basically designed around C, not everybody programs Windows apps in C/C++ and thus might not have the "standard" libraries.

The functions still exist because of backwords compatibility. New code should probably avoid them and stick to the standard C/C++ functions unless there's a real good reason not to.

Share this post


Link to post
Share on other sites
I just tried to write a program to benchmark the difference, but the results were very weird. Here's my code

#include <iostream>
#include <windows.h>

using namespace std;

int main()
{
char bob[256];
int i;
timeBeginPeriod(1);
DWORD time = timeGetTime();
for(i = 0; i < 10000000; ++i)
strcpy(bob, "I am the so evil trevaaar! All you people hear me!");
cout << "Finished 10000000 strcpy's in " << timeGetTime() - time << "ms" << endl;
time = timeGetTime();
for(i = 0; i < 10000000; ++i)
lstrcpy(bob, "I am the so evil trevaaar! All you people hear me!");
cout << "Finished 10000000 lstrcpy's in " << timeGetTime() - time << "ms" << endl;
time = timeGetTime();
for(i = 0; i < 10000000; ++i)
strlen(bob);
cout << "Finished 10000000 strlen's in " << timeGetTime() - time << "ms" << endl;
time = timeGetTime();
for(i = 0; i < 10000000; ++i)
lstrlen(bob);
cout << "Finished 10000000 lstrlen's in " << timeGetTime() - time << "ms" << endl;
timeEndPeriod(1);

return 0;
}


My strcpy and strlen always come up as taking 0ms, no matter how many operations I make. lstrcpy and lstrlen take a more realistic time.

Share this post


Link to post
Share on other sites
Sounds like an optimization issue. Try disabling optimizations in your compile settings, or doing something more complex that the compiler probably won't be able to simply strip out. I suspect that since strcpy()/strlen() can be compiled as intrinsics (rather than requiring the CRT) the compiler is smart enough to remove them, while it can't optimize out lstrcpy()/lstrlen() because they are late bound to the Win32 API.

See here for more on eliminating the CRT.

Share this post


Link to post
Share on other sites
OK. With optimizations turned off, strcpy and strlen run at a much more realistic speed. It's about twice as fast as the Win32 API implementations.

Share this post


Link to post
Share on other sites
Another important thing to remember with the string manipulation functions is that for example lstrcmp operates according to the current user locale. It also handles MBCS and does word sort (so that "bill" and "bill's" are sorted together). strcmp operates on the "C" locale by default, but it can be changed by a call to setlocale. That means that lstrcmp and strcmp almost never return the same result.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this