所有对象typesT的sizeof(T)> = alignof(T)总是如此吗?
对于任何对象typesT
, sizeof(T)
总是至less与alignof(T)
一样大?
直观地看起来如此,因为即使你调整对象的alignment方式,如:
struct small { char c; };
通常情况下,它们的“大小”也是向上调整的,以便数组中对象之间的关系在保持alignment的情况下是有意义的(至less在我的testing中,例如:
struct alignas(16) small16 { char c; };
具有16的大小和alignment。
至less在标准的C ++中,对于任何可以创build数组(长度大于1)的数组,都必须是真实的。 如果你有
Foo arr[2];
和alignof(Foo) > sizeof(Foo)
,那么arr[0]
和arr[1]
不能同时alignment。
正如Zalman Stern的例子所显示的那样,至less有些编译器会允许你声明一个大于它的大小的types,结果是编译器不会让你声明这个types的数组。 这不是符合标准的C ++(它使用types属性,这是一个GCC扩展 ),但是这意味着你可以在实践中alignof(T) > sizeof(T)
。
数组参数假设sizeof(Foo) > 0
,对于标准支持的任何types都是如此,但是o11c显示了一个编译器扩展破坏了这个保证的例子:一些编译器允许0长度的数组,具有0的sizeof
和正的alignof
。
#include <iostream> typedef double foo __attribute__ ((aligned (64))); alignas(64) double bar; double baz __attribute__ ((aligned (64))); int main(int argc, char *argv[]) { std::cout << "foo sizeof: " << sizeof(foo) << " alignof: " << alignof(foo) << "\n"; std::cout << "bar sizeof: " << sizeof(bar) << " alignof: " << alignof(decltype(bar)) << "\n"; std::cout << "baz sizeof: " << sizeof(baz) << " alignof: " << alignof(decltype(baz)) << "\n"; }
编译:
clang++ -std=c++11 alignof_test.cpp -o alignof_test && ./alignof_test
输出:
foo sizeof: 8 alignof: 64 bar sizeof: 8 alignof: 8 baz sizeof: 8 alignof: 8
所以严格来说,不,但上面的说法是:数组必须被保留。
根据引入了alignof
运算符的c ++ 11标准 , sizeof
定义如下(见5.3.3 expr.sizeof):
sizeof运算符产生其操作数的对象表示中的字节数
而alignof
定义是(见5.3.6 expr.alignof):
alignofexpression式产生操作数types的alignment要求。
由于alignof
的定义规定了一个可能由用户做出的要求,而不是规定的语言,我们可以操作编译器:
typedef uint32_t __attribute__ ((aligned (64))) aligned_uint32_t; std::cout << sizeof(aligned_uint32_t) << " -> " << alignof(aligned_uint32_t); // Output: 4 -> 64
编辑
正如其他人所指出的那样,这种types不能用于数组,例如试图编译以下内容:
aligned_uint32_t arr[2];
error: alignment of array elements is greater than element size
结果error: alignment of array elements is greater than element size
由于数组需要指定的types来符合条件: sizeof(T) >= alignof(T)
许多编译器允许大小为0
数组。 alignment保持与鞋底元件的alignment相同。
(除此之外,这对于在不能使用位域的情况下强制进行特定alignment很有用)