2013-08-31 124 views
2

警告:缩小从'unsigned int'到'WORD {aka short unsigned int}'中{'(stride * 4u)'的转换在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,所有内容,但我一直得到相同或相似的警告。

+2

使用大括号初始化可以防止在C++ 11中缩小转换次数。如果这是你的意图,你有没有试过在明确的转换中包装'stride * sizeof(gs_scalar)'? – goji

+0

这是C++ 11中的错误*,不是警告... –

回答

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.Offsetstride * sizeof(gs_scalar)

类型的sizeof(gs_scalar)std::size_t这显然是unsigned int您的平台上,并且stride类型是unsigned(即unsigned int),所以stride * sizeof(gs_scalar)类型是unsigned int。但NORMALELEMENT.Offset的类型是WORD,它是unsigned short

我猜你的平台上unsigned int为32位宽,但unsigned short只有16位宽,所以这确实是一个收缩转换(如果stride * sizeof(gs_scalar)值不适合在16位,你会丢失数据) 。

即使您将stride定义为WORD,也会将其与sizeof(gs_scalar)相乘而提升为unsigned int,因此情况保持不变。

如果您确信stride * sizeof(gs_scalar)绝不会超过USHRT_MAX(即你2 -1即65535),这很可能(在本例中是3 * 4,即12),那么你可以使用(如特洛伊在评论中所说),例如static_cast<WORD>(stride * sizeof(gs_scalar))

+0

非常感谢您的解决! – Goombert

2

strideunsigned所以它的值可能太大而不适合unsigned short。此外,sizeof的类型为std::size_t,它也大于WORD

如果您制作stride a const unsigned,那么编译器可以看到实际值12确实符合unsigned short并且错误消失。但是如果它不是一个常量,你需要明确保证计算结果是合适的,因为大括号内的初始化程序不允许截断或溢出。 (“缩小”是指丢失数据,暗指切断数字的一端的数字。)

只需使用static_cast<WORD>(…)

+0

谢谢你解决了警告!很棒,你们俩。 – Goombert

+0

关于'const'的东西很有趣。 –

+1

@ user2734025请注意,如果有帮助请点击勾号,如果它解决了问题。谢谢你的问题。 – Potatoswatter

相关问题