Narrowing将unsigned int转换为short unsigned int [英] Narrowing Conversion of unsigned int to 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 $ c $我想你的平台
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屋!