Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> как избавиться от варнинга? comparison is always true 
V
    Опции темы
boostcoder
Дата 29.4.2012, 12:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



привет.

имеется такой код, найденный на этом форуме:
http://forum.vingrad.ru/index.php?showtopi...t&p=1803380
http://forum.vingrad.ru/index.php?showtopi...t&p=1803439

Код

#include <string>
#include <iostream>
#include <sstream>
#include <typeinfo>

template <class To, class From>
class TypeConverter {
public:
   static To Convert(const From& from) {
      std::stringstream stream;
      stream << from;
      To value;
      //Check if stream is bad
      if ( stream.bad() )
      {
         throw std::bad_exception();
      }
      //Check if stream contains variable type you want to get
      if ((stream >> value).fail() || !stream.eof())
      {
         throw std::bad_cast();
      }
      return value;
   }
};
template <class From>
class TypeConverter<std::string, From>
{
public:
   static std::string Convert(const From& from) {
      std::stringstream stream;
      stream << from;
      return stream.str();
   }
};
template <>
class TypeConverter<std::string, std::string>
{
public:
   static std::string Convert(const std::string& from) {
      return from;
   }
};
template <>
class TypeConverter<std::string, std::wstring>
{
public:
   static std::string Convert(const std::wstring& from) {
      std::string result;
      for (std::wstring::const_iterator it = from.begin(); it != from.end(); ++it)
      {
         short nchar = *it;
         if (nchar <= 0x7F) {
            result += (char)*it;
         } else if (nchar <= 0x07FF) {
            result += (0xC0 | (nchar >> 6));
            result += (0x80 | (nchar & 0x3F));
         } else if (nchar <= 0xFFFF) {
            result += (0xE0 | (nchar >> 12));
            result += (0x80 | ((nchar >> 6) & 0x3F));
            result += (0x80 | (nchar & 0x3F));
         } else if (*it <= 0x1FFFFF) {
            result += (0xF0 | (nchar >> 18));
            result += (0x80 | ((nchar >> 12) & 0x3F));
            result += (0x80 | ((nchar >> 6) & 0x3F));
            result += (0x80 | (nchar & 0x3F));
         }
      }
      return result;
   }
};

template <>
class TypeConverter<std::wstring, std::string>
{
public:
    static std::wstring Convert(const std::string& from) {
        std::wstring result;
        unsigned char nchar;
        wchar_t tmp = 0;
        for (std::string::const_iterator it = from.begin(); it != from.end(); ++it)
        {
            nchar = (unsigned char)*it;
            if (nchar <= 0x7F) {
                tmp = nchar;
            } else if ((nchar & 0xE0) == 0xC0) {
                tmp = (nchar & 0x1F) << 6;
                nchar = (unsigned char)*(++it);
                tmp |= nchar & 0x3F;
            } else if ((nchar & 0xF0) == 0xE0) {
                tmp = (nchar & 0x0F) << 12;
                nchar = (unsigned char)*(++it);
                tmp |= (nchar & 0x3F) << 6;
                nchar = (unsigned char)*(++it);
                tmp |= (nchar & 0x3F);
            } else if ((nchar & 0xF1) == 0xF0) {
                tmp = (nchar & 0x0F) << 18;
                nchar = (unsigned char)*(++it);
                tmp |= (nchar & 0x3F) << 12;
                nchar = (unsigned char)*(++it);
                tmp |= (nchar & 0x3F) << 6;
                nchar = (unsigned char)*(++it);
                tmp |= (nchar & 0x3F);
            }
            result += tmp;
        }
        return result;
    }
};

//lexical_cast function for all types which supports stream I/O
template <class T, class U>
T lexical_cast(const U& from) {
   return TypeConverter<T, U>::Convert( from );
}

int main() {
   std::cout << lexical_cast<std::string, std::wstring>(L"блаблабла") << std::endl;
}

http://liveworkspace.org/code/7d2a9cad3fd9...d524558e9106467

этот код используется в одном из моих проектов, и, честно говоря, уже врос в проект.
при сборке получаю такой варнинг:
Цитата

source.cpp: In static member function 'static std::string TypeConverter<std::basic_string<char>, std::basic_string<wchar_t> >::Convert(const wstring&)':
source.cpp:58:30: warning: comparison is always true due to limited range of data type [-Wtype-limits]

и он меня уже задрал %)

причина варнинга  - понята. не понимаю как его исправить.

использовать '-Wtype-limits' не хочется.

спасибо.

PM WWW   Вверх
alexvs11
Дата 29.4.2012, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 21.8.2010

Репутация: 6
Всего: 10



Цитата(boostcoder @  29.4.2012,  12:44 Найти цитируемый пост)
short nchar = *it;

это не тот случай, когда используют wint_t?
почему не кастовать в unsigned int?
размер ни самого short'a, ни wchar_t не фиксирован
при желании здесь может быть ошибка конвертирования (когда wchar_t 4 байта, а short - 2) или у меня паранойя?
PM MAIL   Вверх
volatile
Дата 29.4.2012, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Да, похоже это был изначально виндовый код.

boostcoder, я не вникал глубоко в алгоритм.
может просто заменить шорт на wchar_t
http://liveworkspace.org/code/64065aa254c8...6cf345fc2d9fd24
изменил только 52 строчку
?

PM MAIL   Вверх
boostcoder
Дата 29.4.2012, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



да, можно и на wchar_t заменить. катит. ибо он на линуксе, по умолчанию равняется 32ум битам.

спасибо.
вопрос закрыт.

PM WWW   Вверх
volatile
Дата 29.4.2012, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Ну тогда и последнюю елс-иф, 62 строчку
 else if (*it <= 0x1FFFFF) {

заменить на 

 else if (nchar  <= 0x1FFFFF) {

в целях оптимизации. похоже она (nchar) только для оптимизации и введена.
PM MAIL   Вверх
boostcoder
Дата 29.4.2012, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



так будет правильней всего: std::wstring::value_type nchar = *it;
PM WWW   Вверх
volatile
Дата 29.4.2012, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



boostcoder, вообще код какой-то любительско-велосипедный

Вот здесь, например, вообще ошибка (96 строка):
Цитата(boostcoder @  29.4.2012,  12:44 Найти цитируемый пост)
          } else if ((nchar & 0xF1) == 0xF0) {

должно быть:
Цитата
          } else if ((nchar & 0xF8) == 0xF0) {

пруф от  borisbn
http://ru.wikipedia.org/wiki/UTF8
Цитата

0x00010000 — 0x001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx музыкальные символы, редкие китайские иероглифы, вымершие формы письменности 

Символы, конечно редкие, но тем не менее.

Возможно что и еще есть ошибки. Заметил _абсолютно_ случайно.

PM MAIL   Вверх
boostcoder
Дата 30.4.2012, 00:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



volatile, спасибо, исправил smile 
код не я писал. так что особо не проверял.
но и проблем до сих пор не замечал.

PM WWW   Вверх
boostcoder
Дата 1.6.2012, 19:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



приподниму ненадолго тему.

попробовал собрать этот код на MSVC-2008, и получил:
Цитата

warning C4333: '>>' : right shift by too large amount, data loss

люди добрые, подскажите как поправить? smile 

код. строка 63.

спасибо.

PM WWW   Вверх
boostcoder
Дата 1.6.2012, 19:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



это наверное из-за того, что sizeof(wchar_t) на WIN платформе равняется 16..
PM WWW   Вверх
volatile
Дата 1.6.2012, 23:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(boostcoder @  1.6.2012,  19:30 Найти цитируемый пост)
 из-за того, что sizeof(wchar_t) на WIN платформе равняется 16.. 

ага.
В принципе там до последнего ифа вообще никогда дело не дойдет, так как 
Цитата

       } else if (nchar <= 0xFFFF) {

все числа удовлетворяют предпоследнему ифу.


PM MAIL   Вверх
boostcoder
Дата 1.6.2012, 23:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



volatile, спасибо, конечно. так а от варнинга как избавится? smile
PM WWW   Вверх
volatile
Дата 2.6.2012, 00:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(boostcoder @  1.6.2012,  23:47 Найти цитируемый пост)
так а от варнинга как избавится? 

а х.з.  smile 
Ну, как вариант, отлючить компиляцию последнего ифа вообще:
#if WCHAR_MAX > 0xffff
      тут последний иф
#endif


PM MAIL   Вверх
volatile
Дата 2.6.2012, 00:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(volatile @  2.6.2012,  00:24 Найти цитируемый пост)
#if WCHAR_MAX > 0xffff
      тут последний иф
#endif

Да, таки я подумал, это будет наиболее оптимально. Так как при двухбайтном wchar'е, до этого участка дело, полюбому никогда не дойдет. Значит и отлючить его правильно.
В Никсах (при широком wchar'е) останется как и было.

Вообще-то, там по правилам, для этих редких символов, нужно вроде два 2-байтных wchar'а вставлять. Но алгоритма их вычисления я не знаю. А вообще надо бы юзать какие-то более продвинутые библиотеки.
Короче, для данного простого кода, это неплохой выход, имхо.
PM MAIL   Вверх
boostcoder
Дата 2.6.2012, 01:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



volatile, спасибо.
как снова попаду в венду - проверю.

PM WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0968 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.