Narrowing Conversion of unsigned int to short unsigned int

前端 未结 2 1644
情书的邮戳
情书的邮戳 2021-01-22 07:24

warning: narrowing conversion of \'(stride * 4u)\' from \'unsigned int\' to \'WORD {aka short unsigned int}\' inside { } is ill-formed in C++11 [-Wnarrowing]

2条回答
  •  深忆病人
    2021-01-22 07:55

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

提交回复
热议问题