Question

I don't understand why the commented and uncommented line don't yield the same result (Linux GCC, with C++11 flag enabled):

#include "immintrin.h"


typedef __m256 floatv;

struct floatv2{
public:

    //floatv2(const float f):x(_mm256_setzero_ps() + f ), y(_mm256_setzero_ps() + f ) {}; // succeeds
    floatv2(const float f):x{_mm256_setzero_ps() + f }, y{_mm256_setzero_ps() + f } {}; // fails

//private:
    floatv x, y;
};

When trying to compile the uncommented line I get the following error:

error: cannot convert ‘__m256 {aka __vector(8) float}’ to ‘float’ in initialization

which I don't understand because x and y are floatv, not float, so no conversion should be required...

Also, in some more complex code, the first version produces memory access violation. Is there something nasty going on behind the scene?

PS: above the definition of __m256, in avxintrin.h, there is the following comment:

/* The Intel API is flexible enough that we must allow aliasing with other
   vector types, and their scalar components.  */

I don't understand what this means, but feel like it could be related :)

Many thanks

Était-ce utile?

La solution

This is related to DR 1467 which did not allow using the list-initialization syntax for copying aggregates. This was recently fixed for classes in GCC and I extended the fix to vectors in r209449. Gcc-4.10 compiles your code.

Autres conseils

Probably _mm256_setzero_ps() + f returns a float and not a floatv, because f is a float. So you can't initialize floatv values (x and y) with a float using { }, beacuse {}-initialization doesn't allow narrowing (implicit conversion).

Maybe

x{static_cast<__m256>(_mm256_setzero_ps() + f) }

will work.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top