Как обойти предупреждение C4333 ('>>': слишком большой сдвиг вправо, потеря данных) - PullRequest
3 голосов
/ 09 февраля 2011

У меня есть следующая функция для преобразования целого числа произвольного размера в буфер:

template<typename T>
std::string build_data_from(T val)
{
  std::string result;

  for (int i = 0; i < sizeof(val); i++)
  {
    result.insert(0, 1, char(val));
    val = val >> 8;
  }

  return result;
};

Однако при вызове функции шаблона с без знака char в Visual C ++ 2008 выводится предупреждение:

std::string x(build_data_from<unsigned char>(1));

предупреждение C4333: «>>»: сдвиг вправо на слишком большое количество, потеря данных

Есть ли какой-нибудь чистый способ (без использования директивы pragma warning ) обойти это?

Ответы [ 3 ]

3 голосов
/ 16 мая 2012

Следующее избавит от предупреждения.

изменить

val = val >> 8;

на

val = val >> 7 >> 1;

или

val = (val >> 7 >> 1) & 0xff;
2 голосов
/ 09 февраля 2011

Вы можете обойти это с помощью одного if -статирования:

template<typename T>
std::string build_data_from(T val)
{
  std::string result;

  for (size_t i = 0; i < sizeof(val); i++)
  {
    result.insert(0, 1, char(val));
    if (sizeof (T) > 1)
      val = val >> 8;
  }

  return result;
}

Поскольку условное if (sizeof(T) > 1) является постоянным для любого T, компилятор его оптимизирует, поэтому никаких накладных расходов во время выполненияи никаких предупреждений.В случае, если T является char, вы даже получите немного более быстрый код, потому что сдвиг оптимизирован.

Кстати: вы должны объявить переменную i как size_t, а не int,результат sizeof() равен size_t, и некоторые компиляторы (например, gcc) предупреждают вас, если вы сравниваете целые числа со знаком и без знака.

2 голосов
/ 09 февраля 2011

Довольно просто: перегрузка build_data_from для unsigned charchar).

Это может быть сделано либо простой перегрузкой, либо с использованием std::enable_if, я бы посоветовал простую перегрузку какэто будет проще:

std::string build_data_from(char val)
{
  std::string result; result += val; return result;
}

std::string build_data_from(unsigned char val)
{
  return build_data_from(char(val));
}

Но вы понимаете, что приведение unsigned char к char может привести к странным выводам, верно?(Я имею в виду, что unsigned char может иметь значения, которые на самом деле не могут быть напечатаны)

...