Отключить предупреждение в MSVC ++ 2010 - PullRequest
12 голосов
/ 22 июня 2011

У меня есть следующий код:

/** 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;
}

Мой компилятор Все еще показывает мне предупреждение 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)".

(на английском языке: «Преобразование const wchar_t в char, возможная потеря данных, см. Ссылку на создание экземпляра только что скомпилированного шаблона функции…»).

Как я могу его отключить?!

Ответы [ 4 ]

17 голосов
/ 22 июня 2011

Ну, чтобы избавиться от этого предупреждения, вам нужно добавить #pragma warning... вокруг заголовочного файла, который включает в себя функцию. В вашем случае это xutility. Который включен в несколько других файлов. Так что будет сложно найти. Но вы можете попробовать это так.

#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;
}

Кроме того, я бы порекомендовал правильное преобразование. Посмотрите, например, ICU или хотя бы используйте функцию из стандарта. Например. mbstowcs

5 голосов
/ 22 июня 2011

Когда я хочу это сделать, я просто помещаю предупреждение #pragma (disable, 2422) вверху файла .cpp, который нарушает работу, после # include. Но если бы я был тобой, я бы попытался снять предупреждение, а не смести его под ковер. Отказ от константности может привести к неопределенному поведению.

Чтобы устранить предупреждение, попробуйте что-то вроде этого (мы используем эту функцию в нашем решении):

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;
 }

Адаптируйте его для получения const wstring &, должно быть легко, учитывая, что когда вы вызываете c_str () для wstring (), вы получаете const wchar_t *

EDIT : Теперь, когда я еще раз посмотрю на это, его можно еще улучшить, если вы используете RAII для локальной переменной буфера. На всякий случай.

РЕДАКТИРОВАТЬ : исправлен код для учета размера символов

2 голосов
/ 23 июня 2011

Попробуйте изменить свою функцию на что-то подобное (нет компилятора C ++, чтобы проверить, компилируется ли он):

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;
}

(Вдохновленный ответом dario_ramos)

Поскольку вы работаете в Windows, вы можете даже использовать функцию Windows API WideCharToMultiByte, которая в основном делает то же самое, но позволяет указать целевую кодировку.

1 голос
/ 22 июня 2011

Предупреждение не отображается, только если оно отключено перед включением строки h-файла. Думая о причине такого поведения, я предполагаю, что это проблема конкретного шаблона. Когда шаблонный класс включен, компилятор делает вид предварительной компиляции. Полная компиляция выполняется только при создании экземпляра шаблона. Похоже, компилятор VC ++ сохраняет настройки предупреждений на этапе предварительной компиляции, и их изменение до создания экземпляра не помогает.

...