TL;DR
你已经改变了指针类型本身的对齐方式,而不是指针所指向的类型。这与 vector_size 属性无关,与 aligned 属性有关。这也不是一个 bug,在 GCC 和 Clang 中都实现正确。
Long Story
来自 GCC 文档§ 6.33.1 Common Type Attributes(强调添加):
aligned
(alignment)
此属性为 指定类型的变量 指定最小对齐(以字节为单位)。[...]
所讨论的类型是 正在声明的类型,而不是 正在声明的类型指向的类型。因此,
typedef int __attribute__((vector_size(16),aligned(4))) *int4p;
声明一个指向类型为
*T的对象的新类型
T,其中:
- *T是一个16字节向量,默认对齐其大小(16字节)
- T是一个指针类型,此类型的变量可以被异常地存储在低至4字节的边界上(即使它们所指向的是一个更加对齐的类型*T)。
与此同时,§ 6.49通过内置函数使用矢量指令说(重点添加):
On some targets, the instruction set contains SIMD vector instructions which operate on multiple values contained in one large register at the same time. For example, on the x86 the MMX, 3DNow! and SSE extensions can be used this way.
The first step in using these extensions is to provide the necessary data types. This should be done using an appropriate typedef
:
typedef int v4si __attribute__ ((vector_size (16)));
The int
type specifies the base type, while the attribute specifies the vector size for the variable, measured in bytes. For example, the declaration above causes the compiler to set the mode for the v4si
type to be 16 bytes wide and divided into int sized units. For a 32-bit int this means a vector of 4 units of 4 bytes, and the corresponding mode of foo is V4SI.
The vector_size
attribute is only applicable to integral and float scalars, although arrays, pointers, and function return values are allowed in conjunction with this construct. Only sizes that are a power of two are currently allowed.
演示
#include <stdio.h>
typedef int __attribute__((aligned(128))) * batcrazyptr;
struct batcrazystruct{
batcrazyptr ptr;
};
int main()
{
printf("Ptr: %zu\n", sizeof(batcrazyptr));
printf("Struct: %zu\n", sizeof(batcrazystruct));
}
输出:
Ptr: 8
Struct: 128
这与
batcrazyptr ptr
本身的对齐需求更改相一致,而不是其指针对象,并与文档内容一致。
解决方案
恐怕您将被迫使用一系列typedef
,就像您使用int4u
一样。为每个指针级别指定对齐属性是不合理的。