10

In writing Win32 C/C++ code, is there any advantage (e.g. performance?) in using Windows-specific functions like lstrcpyn or CopyMemory instead of the corresponding CRT functions (aside from portability of CRT functions)?

2 Answers2

10

At least some CRT functions use the Win32 functions internally. Also the CRT requires additional initialization (e.g. thread specific data for functions like strtok) and cleanup, that you might not want to have to happen.

You could create a plain Win32 application, without any dependency on anything else including the CRT (much like you could create a plain NT application using NTDLL.DLL - I think smss.exe of Windows is such a process BTW).

Having that said, I think that for most applications that doesn't matter.

UPDATE Since people seem to get so hooked up on the difference of individual functions, in particular memcpy vs. CopyMemory, I would like to add that not all functions in CRT are wrappers around those in Win32. Naturally, some can be implemented without any help from Win32 (actually memcpy is a good example for that), while others (sensibly) can't. Something that, I believe, @Merdad hinted in his answer to.

So, portability aside, I don't think performance is the next best argument for or against using the CRT. You should choose what fits best and that typically will be the CRT. And there is nothing speaking against using individual Win32 functions (with CRT equivalents), where you seem fit.

Christian.K
  • 47,778
  • 10
  • 99
  • 143
  • 1
    It should be noted, as an example of using `memcpy` vs `CopyMemory`, that the Windows SDK headers defines `CopyMemory` as a macro that invokes `RtlCopyMemory` which is a macro that invokes `memcpy`. – Matthew Nov 11 '13 at 21:41
  • Actually, `memcpy`, `memmove`, `memcmp`, `strlen`, and `memset` are all implemented in ntdll.dll. So the CRT functions are still either wrappers for Win32 functions, wrappers for NtDll.dll functions, implementable on their own (e.g. formatting and math), or part of the entry point. For example, Rust doesn't use MSVCRT for anything except math and the entry point, and even that may change soon. – alexchandel Oct 18 '15 at 00:00
3

It depends on the function and your requirements.

For things like memcpy, there isn't any point whatsoever to choosing the Windows-specific versions. Stick with standard C to keep it simple and portable.

For other things like mbstowcs, you might need to use things like MultiByteToWideChar instead -- depending on what functionality you need.

Personally I go for the C versions if possible, and only go for Win32 versions afterwards -- because there's really no reason to write Windows-specific code when it could be written portably.

user541686
  • 205,094
  • 128
  • 528
  • 886
  • 3
    memset is another good example here, you might prefer SecureZeroMemory since it's gauranteed not to be optimized away by the windows compiler. – Benj Jan 21 '12 at 09:28
  • @Benj: Why would the compiler optimize away a call to memset? Could you please elaborate? –  Jan 21 '12 at 09:33
  • 3
    @Mr_C64 - Sure, the compiler might optimize a call to memset if the memory concerned is on the stack and is about to go out of scope. This is fine, except that if the data is sensitive, like a password, it will be left in the stack residue and could be probed later. – Benj Jan 21 '12 at 09:35
  • Have you actually seen a compiler remove a function call? I would call that breakage, not optimization. – Carey Gregory Jan 21 '12 at 16:13
  • 1
    @CareyGregory: It's not a bug, it's a feature. – user541686 Jan 21 '12 at 18:32
  • Mehrdad: As @Benj's example demonstrates, it's not a very desirable "feature." Calling functions for their side effects is a very common practice, so eliminating a function call altogether is likely to produce breakage. – Carey Gregory Jan 22 '12 at 23:13
  • @CareyGregory: It's not just *any* side effect that gets eliminated -- **only** those side effects which **do not affect the behavior of the program** get eliminated (except for RVO, but that's a different issue). Because zeroing memory doesn't affect program behavior, the compiler is free to avoid it. – user541686 Jan 22 '12 at 23:47
  • 1
    @Mehrdad: I understand the rationale for doing so, but I still maintain that eliminating a function call because the compiler mistakenly believes it has no intended effect is highly undesirable. – Carey Gregory Jan 23 '12 at 23:58
  • 2
    The compiler doesn't "mistakenly" believe anything; it's completely correct in its assessment. The example given was about sensitive data remaining on the stack. That **does not** affect the behavior of the program, which is all that the compiler cares about. You can always disable optimizations if things like this scare you. – Cody Gray - on strike Jan 24 '12 at 03:36
  • Of course it affects the behavior of the program. Demonstrably. – Carey Gregory Jan 24 '12 at 14:44