Narrowing将unsigned int转换为short unsigned int [英] Narrowing Conversion of unsigned int to short unsigned int

查看:529
本文介绍了Narrowing将unsigned int转换为short unsigned int的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


警告:缩小'(stride * 4u)'从'unsigned int'到'WORD {aka short unsigned int}'在{}内的转换在C ++ 11中是不成形的[ -Wnarrowing]


我不知道为什么我得到这个警告从MinGW编译以下代码:

  unsigned stride = 3; 

D3DVERTEXELEMENT9 NORMALELEMENT =
{0,stride * sizeof(gs_scalar),D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_NORMAL,0};
if(useNormals)stride + = 3;

正在抱怨 stride * sizeof(gs_scalar)(gs_scalar是 float )在这些花括号,但我不知道这是一个缩小的转换,因为 sizeof 返回字节数。我尝试将 stride 的数据类型更改为WORD,DWORD,CHAR,一切,但我保持相同或类似的警告。

解决方案

查看 D3DVERTEXELEMENT9 的定义:

  struct D3DVERTEXELEMENT9 {
WORD Stream;
WORD Offset;
BYTE类型;
BYTE Method;
BYTE用法;
BYTE UsageIndex;
};

(来自 http://msdn.microsoft.com/en-us/library/windows/desktop/bb172630%28v=vs。



因此你正在初始化 NORMALELEMENT.Offset stride * sizeof(gs_scalar)



std :: size_t ,它显然是平台上的 unsigned int stride unsigned (即 unsigned int ),因此 stride * sizeof(gs_scalar)的类型是 unsigned int 。但是 NORMALELEMENT.Offset 的类型是 WORD ,这是无符号short unsigned int 是32位宽,但 > unsigned short 只有16位宽,因此这的确是一个缩小的转换(如果 stride * sizeof(gs_scalar)



即使您将 stride 定义为 WORD ,在与的乘法中提升为 unsigned int sizeof(gs_scalar),所以情况保持不变。



如果你确定 stride * sizeof(gs_scalar)永远不会超过 USHRT_MAX (即对于你2 16 -1 ie 65535),这似乎可能(在这个例子中是3 * 4 ie 12 ),那么你可以使用一个cast(正如Troy在注释中所说的),eg static_cast< WORD>(stride * sizeof(gs_scalar))


warning: narrowing conversion of '(stride * 4u)' from 'unsigned int' to 'WORD {aka short unsigned int}' inside { } is ill-formed in C++11 [-Wnarrowing]

I cannot figure out why I am getting this warning compiling the following code from MinGW:

unsigned stride = 3;

D3DVERTEXELEMENT9 NORMALELEMENT =
{ 0, stride * sizeof(gs_scalar), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 };
if (useNormals) stride += 3;

It is complaining about the stride * sizeof(gs_scalar) (gs_scalar is float) inside those braces, but I do not see how this is a narrowing conversion since sizeof returns the number of bytes. I tried changing stride's data type to WORD, DWORD, CHAR, everything, but I keep getting the same or similar warning.

解决方案

Look at the definition of D3DVERTEXELEMENT9:

struct D3DVERTEXELEMENT9 {
  WORD Stream;
  WORD Offset;
  BYTE Type;
  BYTE Method;
  BYTE Usage;
  BYTE UsageIndex;
};

(from http://msdn.microsoft.com/en-us/library/windows/desktop/bb172630%28v=vs.85%29.aspx but removed the typedef things).

Thus your are initializing NORMALELEMENT.Offset with stride * sizeof(gs_scalar).

The type of sizeof(gs_scalar) is std::size_t which is apparently unsigned int on your platform, and the type of stride is unsigned (i.e. unsigned int), so the type of stride * sizeof(gs_scalar) is unsigned int. But the type of NORMALELEMENT.Offset is WORD which is unsigned short.

I guess that on your platform unsigned int is 32-bits wide but unsigned short only 16-bits wide, so this is indeed a narrowing conversion (if the value of stride * sizeof(gs_scalar) can't fit in 16 bits you'll lose data).

Even if you define stride as a WORD, it is promoted to unsigned int in the multiplication with sizeof(gs_scalar), so the situation keeps the same.

If you're sure that stride * sizeof(gs_scalar) will never be more than USHRT_MAX (i.e. for you 216−1 i.e. 65535), which seems likely (in the example it's 3 * 4 i.e. 12), then you can use a cast (as said by Troy in the comments), e.g. static_cast<WORD>(stride * sizeof(gs_scalar)).

这篇关于Narrowing将unsigned int转换为short unsigned int的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆