开发者

How to workaround warning C4333 ('>>' : right shift by too large amount, data loss)

开发者 https://www.devze.com 2023-02-09 06:40 出处:网络
I have the following function to convert an integer of arbitrary size to a buffer: template<typename T>

I have the following function to convert an integer of arbitrary size to a buffer:

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;
}开发者_JAVA百科;

However, invoking the template function with an unsigned char renders a warning in Visual C++ 2008:

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

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

Is there any clean way (without using a pragma warning directive) to workaround it?


The following will get rid of he warning.

change

val = val >> 8;

to

val = val >> 7 >> 1;

or

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


Pretty simple: overloading build_data_from for unsigned char (and char).

This can be done either by a plain overload or using std::enable_if, I'd advise a plain overload as it'll be easier:

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

But, you are conscious that casting an unsigned char to a char might produce some weird output right ? (I mean that unsigned char might have values that are not really printable)


You can get around this with a single if-statement:

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

Since the conditional if (sizeof(T) > 1) is constant for any T the compiler will optimize it away, so no runtime overhead and no warnings. For the case that T is a char you even get slightly faster code because the shift gets optimized away.

Btw: You should declare your i variable as size_t, not int. the result of sizeof() is size_t and some compilers (gcc for example) warn you if you do a comparison between signed and unsigned integers.

0

精彩评论

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