简体   繁体   English

将unsigned int转换为short unsigned int

[英]Narrowing Conversion of unsigned int to 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] 警告:在{}中将'(stride * 4u)'从'unsigned int'转换为'WORD {aka short unsigned int}'的转换在C ++ 11中格式不正确[-Wnarrowing]

I cannot figure out why I am getting this warning compiling the following code from MinGW: 我无法弄清楚为什么从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. 它抱怨这些括号内的stride * sizeof(gs_scalar) (gs_scalar是float ),但是由于sizeof返回字节数,所以我看不到这是如何缩小转换的。 I tried changing stride 's data type to WORD, DWORD, CHAR, everything, but I keep getting the same or similar warning. 我尝试将stride的数据类型更改为WORD,DWORD,CHAR,所有内容,但我不断收到相同或相似的警告。

Look at the definition of D3DVERTEXELEMENT9 : 看一下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). (来自http://msdn.microsoft.com/zh-cn/library/windows/desktop/bb172630%28v=vs.85%29.aspx,但删除了typedef内容)。

Thus your are initializing NORMALELEMENT.Offset with stride * sizeof(gs_scalar) . 因此,您正在使用NORMALELEMENT.Offset stride * sizeof(gs_scalar)初始化NORMALELEMENT.Offset

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 (ie unsigned int ), so the type of stride * sizeof(gs_scalar) is unsigned int . sizeof(gs_scalar)的类型是std::size_t ,在您的平台上显然是unsigned int ,而stride的类型是unsigned (即unsigned int ),因此stride * sizeof(gs_scalar)的类型是unsigned int But the type of NORMALELEMENT.Offset is WORD which is unsigned short . 但是NORMALELEMENT.Offset的类型是WORD ,它是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). 我猜您的平台上unsigned int宽度为32位,而unsigned short宽度仅为16位,所以这确实是一个缩小的转换(如果stride * sizeof(gs_scalar)值不能适合16位,您将丢失数据)。

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. 即使将stride定义为WORD ,在与sizeof(gs_scalar)的乘法运算中它也会被提升为unsigned int ,因此情况保持不变。

If you're sure that stride * sizeof(gs_scalar) will never be more than USHRT_MAX (ie for you 2 16 −1 ie 65535), which seems likely (in the example it's 3 * 4 ie 12), then you can use a cast (as said by Troy in the comments), eg static_cast<WORD>(stride * sizeof(gs_scalar)) . 如果您确定stride * sizeof(gs_scalar)永远不会超过USHRT_MAX (即对于您来说2 16 -1即65535),这似乎是可能的(在示例中为3 * 4即12),那么您可以使用static_cast<WORD>(stride * sizeof(gs_scalar)) (如Troy在评论中所说),例如static_cast<WORD>(stride * sizeof(gs_scalar))

stride is unsigned so its value could be too large to fit into an unsigned short . strideunsigned因此其值可能太大而无法容纳unsigned short Furthermore sizeof has type std::size_t which is also larger than WORD . 此外sizeof类型为std::size_t ,它也比WORD

If you make stride a const unsigned , then the compiler can see that the actual value 12 does fit into unsigned short and the error goes away. 如果将stride设为const unsigned ,那么编译器可以看到实际值12确实适合unsigned short ,并且错误消失了。 But if it is not a constant, you need to explicitly guarantee that the calculation will fit because initializers inside braces are not allowed to truncate or overflow. 但是,如果它不是常数,则需要明确保证计算将适合,因为不允许括号内的初始化程序截断或溢出。 ("Narrowing" refers to losing data, alluding to chopping off digits on one end of a number.) (“缩小”是指丢失数据,暗示切掉数字的一端的数字。)

Just use static_cast< WORD >( … ) . 只需使用static_cast< WORD >( … )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM