开发者

Disable warning in MSVC++2010

I ha开发者_Go百科ve the following code:

/** Stupidly copies unicode chars into normal chars. */
std::string wstring2string(__in  const std::wstring& s)
{
    std::string temp(s.length(), ' ');
#pragma warning(push)
#pragma warning(disable: 4244) // possible loss of data
    std::copy(s.begin(), s.end(), temp.begin());
#pragma warning(pop)
    return temp;
}

My compiler still shows me warning C4244:

1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(2144): warning C4244: '=': Konvertierung von 'const wchar_t' in 'char', möglicher Datenverlust
1>          c:\program files\microsoft visual studio 10.0\vc\include\xutility(2165): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "_OutIt std::_Copy_impl<_InIt,_OutIt>(_InIt,_InIt,_OutIt,std::_Nonscalar_ptr_iterator_tag)".

(in English: "Conversion of const wchar_t to char, possible loss of data, see reference to instantiation of the just compiled function template …").

How can I disable it?!


Well to get rid of this warning you need to add the #pragma warning... around your header file that includes the function. In your case this is xutility. Which is included by multiple other files. So it will be difficult to find. But you can try it this way.

#pragma warning(push)
#pragma warning(disable: 4244) // possible loss of data
#include <xutility>
#pragma warning(pop)
Your includes go here...
std::string wstring2string(__in  const std::wstring& s)
{
    std::string temp(s.length(), ' ');
    std::copy(s.begin(), s.end(), temp.begin());
    return temp;
}

Beside of this I would recommend to a correct conversion. Have a look at ICU for example or at least use the function from standard. E.g. mbstowcs


When I want to do that, I just put #pragma warning( disable, 2422 ) at the top of the offending .cpp file, after the #include's. But if I were you, I'd try to solve the warning instead of sweeping it under the carpet. Casting away constness might result in undefined behavior.

To solve the warning, try something like this (we use this function in our solution):

string wtoString( const wchar_t *ws ){
        size_t bufferSize = (wcslen(ws) + 1) * sizeof(wchar_t);
        char * buffer = new char[ bufferSize ];
        size_t convertedChars;
        wcstombs_s( &convertedChars, buffer, bufferSize, ws, _TRUNCATE);
        string result(buffer);
        delete[] buffer;
        return result;
 }

Adapt it to receive a const wstring&, it should be easy considering that when you call c_str() for a wstring(), you get a const wchar_t*

EDIT: Now that I look at this again, it can be further improved if you use RAII for the buffer local variable. Just in case.

EDIT: Corrected code to consider character size


Try to change your function to something like this (no C++ compiler available to check if it compiles):

std::string wstring2string(__in const std::wstring& s)
{
    size_t bufferSize;

    // first call to wcstombs_s to get the target buffer size
    wcstombs_s(&bufferSize, NULL, 0, ws.c_str(), ws.size());

    // create target buffer with required size
    char* buffer = new char[bufferSize];

    // second call to do the actual conversion
    wcstombs_s(&bufferSize, s.c_str(), bufferSize, ws.c_str(), ws.size());

    string result(buffer, bufferSize);
    delete[] buffer;
    return result;
}

(Inspired by dario_ramos answer)

As you are on Windows, you could even use the Windows API function WideCharToMultiByte, which basically does the same but allows you to specify the target encoding.


The warning is not shown only if it is disabled before including string h-file. Thinking about the reason of this behavior, I guess that this is template-specific issue. When template class is included, compiler makes kind of pre-compilation. Full compilation is done only when template is instantiated. It looks like VC++ compiler keeps warning settings from pre-compilation stage, and changing them before instantiation doesn't help.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜