简体   繁体   中英

error: narrowing conversion of ‘18446744069414584320ull’ from ‘long long unsigned int’ to ‘int’ inside { } [-Wnarrowing]

What is wrong with this piece of code? I'm using GCC 6.3.

https://ideone.com/ektGEp

a.cpp: In function 'int main()':`a.cpp:26:24: error: narrowing conversion of '18446744069414584320ull' from 'long long unsigned int' to 'int' inside { } [-Wnarrowing]

#include <iostream>
using namespace std;
#include <smmintrin.h>
#include <emmintrin.h>
#include <tmmintrin.h>

typedef union {
        __m64  mm64[2];
        __m128 mm128i;
} sse2_t;

#define const_epi32( i3,i2,i1,i0 )      \
            { static_cast<unsigned long long> (static_cast<unsigned long long>(i1) << 32), \
              static_cast<unsigned long long> (static_cast<unsigned long long>(i3) << 32) }

int main() {

        sse2_t arr_val[3] = { const_epi32(0,-1,0,-1),
                          const_epi32(0, 0,-1, -1),
                          const_epi32(0, 0,0, 1024) 
                        }; //error!

        sse2_t val = const_epi32(0,-1,0,-1); // ok!
        // your code goes here
        return 0;
}

The types __m64 and __m128 are very special, representing vector registers, which means that you cannot assign values to them in the usual way (like you seem to be trying to do in your code). You need to use special load functions to put data into registers, and special store functions to get data back from there.

Here is an example of how you could load data (four floats) into a __m128 variable:

#include <cstring>
#include <smmintrin.h>
int main() {
  float f[4];
  memset(f, 0, 16);
  __m128 a = _mm_load_ps(f);
  return 0;
}

This page has lots of info about all the different types and intrinsic functions available: https://software.intel.com/sites/landingpage/IntrinsicsGuide/

#define const_epi32( i3,i2,i1,i0 )      \
        { _m_from_int64( (static_cast<unsigned long long>(i1) << 32), \
          _m_from_int64( (static_cast<unsigned long long>(i3) << 32) }

The part const_epi32(0, 0,-1, -1) is causing the warning since you are assigning '0xffffFFFFffffFFFF' to a 32 bit 'int' which is narrowing.

I assume the other cases do not cause a warning since the assigned value is a constant 0 which does not suffer from narrowing.

The other question is, why is __m64 an int . I assume that __m64 cannot be directly assigned to (being an MM register) and that the narrowing check (at least for constant assignment) is bogus in the compiler.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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