对于所有对象类型 T,sizeof(T) >= alignof(T) 总是这样吗?
Is it always the case that sizeof(T) >= alignof(T) for all object types T?
对于任何对象类型 T
是否总是 sizeof(T)
至少与 alignof(T)
一样大?
直觉上似乎是这样,因为即使您像这样调整对象的对齐方式:
struct small {
char c;
};
在正常情况下,它们的 "size" 也向上调整,以便数组中对象之间的关系在保持对齐的同时有意义(至少在我的 testing 中是这样。例如:
struct alignas(16) small16 {
char c;
};
大小和对齐方式均为 16。
至少在标准 C++ 中,对于任何你可以创建数组(长度 > 1)的东西,这都必须是真的。如果你有
Foo arr[2];
和alignof(Foo) > sizeof(Foo)
,那么arr[0]
和arr[1]
不能同时对齐。
As shows, though, at least some compilers will allow you to declare a type with alignment greater than its size, with the result that the compiler simply won't let you declare an array of that type. This is not standards-compliant C++ (it uses type attributes, which are a GCC extension), 但这意味着你在实践中可以有alignof(T) > sizeof(T)
.
数组参数采用 sizeof(Foo) > 0
,这对于标准支持的任何类型都是正确的,但是 编译器扩展破坏该保证的示例:一些编译器允许 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 standard,sizeof
定义如下(见5.3.3 expr.sizeof):
The sizeof operator yields the number of bytes in the object representation of its operand
而alignof
定义是(见5.3.6expr.alignof):
An alignof expression yields the alignment requirement of its operand type.
由于 alignof
的定义指定了可能由用户提出的要求,而不是语言规范,我们可以操纵编译器:
typedef uint32_t __attribute__ ((aligned (64))) aligned_uint32_t;
std::cout << sizeof(aligned_uint32_t) << " -> " << alignof(aligned_uint32_t);
// Output: 4 -> 64
已编辑
正如其他人所指出的,此类类型不能在数组中使用,例如尝试编译以下内容:
aligned_uint32_t arr[2];
结果 error: alignment of array elements is greater than element size
由于数组要求指定类型符合条件:sizeof(T) >= alignof(T)
许多编译器允许大小为 0
的数组。对齐方式与唯一元素的对齐方式保持一致。
(除其他外,这对于在无法使用位域的情况下强制执行特定对齐非常有用)
对于任何对象类型 T
是否总是 sizeof(T)
至少与 alignof(T)
一样大?
直觉上似乎是这样,因为即使您像这样调整对象的对齐方式:
struct small {
char c;
};
在正常情况下,它们的 "size" 也向上调整,以便数组中对象之间的关系在保持对齐的同时有意义(至少在我的 testing 中是这样。例如:
struct alignas(16) small16 {
char c;
};
大小和对齐方式均为 16。
至少在标准 C++ 中,对于任何你可以创建数组(长度 > 1)的东西,这都必须是真的。如果你有
Foo arr[2];
和alignof(Foo) > sizeof(Foo)
,那么arr[0]
和arr[1]
不能同时对齐。
As alignof(T) > sizeof(T)
.
数组参数采用 sizeof(Foo) > 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 standard,sizeof
定义如下(见5.3.3 expr.sizeof):
The sizeof operator yields the number of bytes in the object representation of its operand
而alignof
定义是(见5.3.6expr.alignof):
An alignof expression yields the alignment requirement of its operand type.
由于 alignof
的定义指定了可能由用户提出的要求,而不是语言规范,我们可以操纵编译器:
typedef uint32_t __attribute__ ((aligned (64))) aligned_uint32_t;
std::cout << sizeof(aligned_uint32_t) << " -> " << alignof(aligned_uint32_t);
// Output: 4 -> 64
已编辑
正如其他人所指出的,此类类型不能在数组中使用,例如尝试编译以下内容:
aligned_uint32_t arr[2];
结果 error: alignment of array elements is greater than element size
由于数组要求指定类型符合条件:sizeof(T) >= alignof(T)
许多编译器允许大小为 0
的数组。对齐方式与唯一元素的对齐方式保持一致。
(除其他外,这对于在无法使用位域的情况下强制执行特定对齐非常有用)