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
.