如何解决警告C4333('>>':右移太大,数据丢失)

时间:2011-02-09 16:01:17

标签: c++ visual-studio visual-c++ compiler-warnings

我有以下函数将任意大小的整数转换为缓冲区:

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

但是,使用 unsigned char 调用模板函数会在Visual C ++ 2008中显示警告:

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

警告C4333:'&gt;&gt;' :右移   数量太大,数据丢失

有没有干净的方法(不使用 pragma warning 指令)来解决它?

3 个答案:

答案 0 :(得分:3)

以下将摆脱他的警告。

更改

val = val >> 8;

val = val >> 7 >> 1;

val = (val >> 7 >> 1) & 0xff;

答案 1 :(得分:2)

非常简单:为build_data_from(和unsigned char)重载char

这可以通过普通过载或使用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可能具有不可打印的值)

答案 2 :(得分:2)

您可以使用单个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都是常量,编译器将对其进行优化,因此没有运行时开销和警告。对于Tchar的情况,您甚至可以获得稍快的代码,因为转移得到了优化。

顺便说一句:您应该将i变量声明为size_t,而不是intsizeof()的结果是size_t,如果你对有符号和无符号整数进行比较,一些编译器(例如gcc)会警告你。