警告:缩小{(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,所有内容,但我仍然收到相同或类似的警告。
答案 0 :(得分:3)
查看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内容。)
因此,您正在使用NORMALELEMENT.Offset
初始化stride * sizeof(gs_scalar)
。
sizeof(gs_scalar)
的类型为std::size_t
,在您的平台上显然为unsigned int
,stride
的类型为unsigned
(即{{1} }),因此unsigned int
的类型为stride * sizeof(gs_scalar)
。但unsigned int
的类型为NORMALELEMENT.Offset
WORD
。
我想你的平台unsigned short
是32位宽,unsigned int
只有16位宽,所以这确实是一个缩小的转换(如果unsigned short
的值可以' t适合16位,你会丢失数据。)
即使您将stride * sizeof(gs_scalar)
定义为stride
,也会在WORD
的乘法中将其提升为unsigned int
,因此情况保持不变。
如果您确定sizeof(gs_scalar)
永远不会超过stride * sizeof(gs_scalar)
(即2 16 -1,即65535),这似乎很可能(在示例中)它是3 * 4即12),那么你可以使用演员(如评论中的特洛伊所说),例如USHRT_MAX
。
答案 1 :(得分:2)
stride
为unsigned
因此其值可能太大而无法容纳unsigned short
。此外,sizeof
的类型std::size_t
也大于WORD
。
如果您将stride
设为const unsigned
,则编译器可以看到实际值12
确实适合unsigned short
,并且错误消失。但是如果它不是常量,则需要明确保证计算适合,因为不允许括号内的初始化程序截断或溢出。 (“缩小”是指丢失数据,暗示在数字的一端切掉数字。)
只需使用static_cast< WORD >( … )
。