+-
c-将unsigned int转换为short unsigned int的转换

warning: narrowing conversion of ‘(stride * 4u)’ from ‘unsigned int’ to ‘WORD {aka short unsigned int}’ inside { } is ill-formed in 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;

它抱怨这些括号内的跨度* sizeof(gs_scalar)(gs_scalar是浮点型),但是由于sizeof返回字节数,因此我看不到这是如何缩小转换的.我尝试将stride的数据类型更改为WORD,DWORD,CHAR,所有内容,但我不断收到相同或相似的警告.

最佳答案
查看D3DVERTEXELEMENT9的定义:

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

(从http://msdn.microsoft.com/en-us/library/windows/desktop/bb172630%28v=vs.85%29.aspx开始,但删除了typedef东西).

因此,您正在使用步幅* sizeof(gs_scalar)初始化NORMALELEMENT.Offset.

sizeof(gs_scalar)的类型为std :: size_t,在您的平台上显然是unsigned int的,而stride的类型是unsigned的(即unsigned int),因此stride * sizeof(gs_scalar)的类型是unsigned int的.但是NORMALELEMENT.Offset的类型是WORD,它是无符号的.

我猜您的平台上unsigned int的宽度为32位,而unsigned short的宽度仅为16位,所以这确实是一个缩小的转换(如果stride * sizeof(gs_scalar)的值不能适合16位,您将丢失数据).

即使将跨步定义为WORD,在与sizeof(gs_scalar)的乘法运算中,跨步也会提升为unsigned int,因此情况保持不变.

如果您确定跨步* sizeof(gs_scalar)永远不会超过USHRT_MAX(即对于您216−1,即65535),这似乎是可能的(在示例中为3 * 4,即12),则可以使用强制转换(如特洛伊在评论中所说),例如static_cast< WORD>(步幅* sizeof(gs_scalar)).

点击查看更多相关文章

转载注明原文:c-将unsigned int转换为short unsigned int的转换 - 乐贴网