I am using GCC 14.1 with C++17, and want to allocate 32 bytes-aligned memory always.
#include <immintrin.h>
#include <vector>
int main() {
std::vector<__m256> d;
}
g++ -std=c++17 -mavx2 test.cpp test.cpp: In function ‘int main()’: test.cpp:5:23: warning: ignoring attributes on template argument ‘__m256’ [-Wignored-attributes] 5 | std::vector<__m256> d;
Why do we see this warning? Thanks.
My understanding is that it should be legal from C++17.
The warning is actually not about std::vector not being able to work with over-aligned types (prior to C++17), but that the __attribute__ of the type is ignored, thus making, e.g. __m256 indistinguishable from __m256_u.
One way to show the meaningfulness of the warning, is if you also have std::vector<__m256_u> (__m256_u is defined by gcc/clang as typedef float __m256_u __attribute__ ((__vector_size__ (32), __may_alias__, __aligned__ (1)));, i.e., the same as __m256 except possibly being unaligned).
From gcc's (and also clang's) point of view the attributes are ignored when passed as template arguments, thus std::vector<__m256_u> and std::vector<__m256> have the same type.
Example where this can cause unintended behavior:
void foo(std::vector<__m256>&);
void bar(std::vector<__m256_u>&);
int main() {
std::vector<__m256> d;
std::vector<__m256_u> e;
foo(d);
foo(e); // should not work, but does because attributes are ignored
bar(d); // should not work, but does because attributes are ignored
bar(e);
}
One possible workaround is to wrap __m256 into a struct, e.g. like so:
struct vec8f {
__m256 data;
vec8f(__m256 x) : data(x) {}
operator __m256() const {return data;}
};
Godbolt-Demo: https://godbolt.org/z/zxsE5bseq
Of course, if you assume that the warning won't affect your code, you could just mask it by compiling with -Wno-ignored-attributes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With