What is wrong with mbstowcs_s in cpp

136 views Asked by At

What is actually wrong with Windows' mbstowcs_s function?

While reading documentation on Microsoft's site, I can clearly see that this function takes only 4 parameters. Also, when I go to the function declaration in my IDE, I get this:

errno_t mbstowcs_s(
_Out_opt_ size_t*,     _PtNumOfCharConverted,
_Post_z_  wchar_t,     _Dest,
_In_z_    char const*, _Source,
_In_      size_t,      _MaxCount
)

But, when I'm passing only 4 parameters, it tells me this:

Error (active) E0304 no instance of overloaded function "mbstowcs_s" matches the argument list

After placing _Dest, I have to put another parameter that is equal to the amount of allocated memory.

I don't actually know what is wrong with this header and documentation, and how it works in this case.

Example:

#include <stdlib.h>
#include <Windows.h>
int main()
{
   const char* line = "12345";
   size_t line_length = 6;
   wchar_t* wchar_name_temp = new wchar_t[line_length];
   size_t outSize;
   mbstowcs_s(&outSize, wchar_name_temp, line, strlen(line));
}

Output:

<source>(9): error C2660: 'mbstowcs_s': function does not take 4 arguments
C:/WinSdk/Include/10.0.18362.0/ucrt\stdlib.h(911): note: see declaration of 'mbstowcs_s'
C:/WinSdk/Include/10.0.18362.0/ucrt\stdlib.h(919): note: could be 'errno_t mbstowcs_s(size_t *,wchar_t (&)[_Size],const char *,size_t) throw()'
<source>(9): note: 'errno_t mbstowcs_s(size_t *,wchar_t (&)[_Size],const char *,size_t) throw()': could not deduce template argument for 'wchar_t (&)[_Size]' from 'wchar_t *'
<source>(9): note: while trying to match the argument list '(size_t *, wchar_t *, const char *, size_t)'
1

There are 1 answers

3
Yksisarvinen On

The overload that takes 4 arguments requires an array, not a pointer. If you want to pass in a pointer, you should choose an overload that passes in size as well.

This will work with C++ overload:

#include <stdlib.h>
#include <Windows.h>
int main()
{
   const char* line = "12345";
   const size_t line_length = 6;
   wchar_t wchar_name_temp [line_length]; //array, not pointer
   size_t outSize;
   mbstowcs_s(&outSize, wchar_name_temp, line, strlen(line));
   // array length is deduced with template magic
}

This will work with C overload:

#include <stdlib.h>
#include <Windows.h>
int main()
{
   const char* line = "12345";
   size_t line_length = 6;
   wchar_t* wchar_name_temp = new wchar_t[line_length]; //can be array or pointer, both are good
   size_t outSize;
   mbstowcs_s(&outSize, wchar_name_temp, line_length, line, strlen(line));
   // array length is passed explicitly  ^~~~~~~~~~~
}