提问者:小点点

对于所有对象类型T,sizeof(T)>=对(T)总是这样吗?


对于任何对象类型Tsizeof(T)是否总是至少与对齐(T)一样大?

直觉上看起来是这样,因为即使你调整对象的对齐方式,比如:

struct small {
  char c;
};

在正常情况下,它们的“大小”也会向上调整,以便数组中对象之间的关系有意义,同时保持对齐(至少在我的测试中)。例如:

struct alignas(16) small16 {
  char c;
};

大小和对齐方式均为16。


共3个答案

匿名用户

至少在标准C中,对于任何你可以制作一个数组的东西(带长度

Foo arr[2];

对齐(Foo)

然而,正如Zalman Stern的例子所示,至少一些编译器允许你声明一个对齐大于其大小的类型,结果编译器根本不允许你声明该类型的数组。这不是符合标准的C(它使用类型属性,这是一个GCC扩展),但这意味着你可以有对齐(T)

数组参数假设sizeof(Foo)

匿名用户

#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

所以严格来说,没有,但是上面的参数re:数组必须保留。

匿名用户

根据引入对齐运算符的c 11标准,sizeof定义如下(参见5.3.3 expr. sizeof):

sizeof运算符产生其操作数的对象表示中的字节数

的定义是(参见5.3.6 expr.对):

对齐表达式产生其操作数类型的对齐要求。

由于对齐的定义指定了可能由用户提出的要求,而不是语言的规范,因此我们可以操作编译器:

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];

导致错误:数组元素的对齐方式大于元素大小

由于数组需要指定的类型符合条件:sizeof(T)