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

Bee*_*ope 42 c++ memory-alignment c++11 alignof

对于任何对象类型T,它总是sizeof(T)至少与大小一样大alignof(T)吗?

直观地看起来如此,因为即使你调整对象的对齐方式,例如:

struct small {
  char c;
};
Run Code Online (Sandbox Code Playgroud)

通常情况下,它们的"大小"也会向上调整,以便在保持对齐的同时,阵列中对象之间的关系是有意义的(至少在我的测试中.例如:

struct alignas(16) small16 {
  char c;
};
Run Code Online (Sandbox Code Playgroud)

两者的大小和对齐都是16.

use*_*ica 30

至少在标准C++中,对于任何你可以制作数组(长度> 1)的东西,这都必须是真的.如果你有

Foo arr[2];
Run Code Online (Sandbox Code Playgroud)

并且alignof(Foo) > sizeof(Foo),然后arr[0]arr[1]不能同时对齐.

正如Zalman Stern的例子所示,至少有些编译器会允许你声明一个对齐大于其大小的类型,结果是编译器根本不会让你声明一个这种类型的数组.这不符合标准的C++(它使用类型属性,它是GCC扩展),但这意味着您可以alignof(T) > sizeof(T)在实践中使用.

数组参数假定sizeof(Foo) > 0,对于标准支持的任何类型都是如此,但是o11c显示了编译器扩展破坏了该保证的示例:一些编译器允许0长度数组,0 sizeof和正数alignof.


Zal*_*ern 12

#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";
}
Run Code Online (Sandbox Code Playgroud)

编译:

clang++ -std=c++11 alignof_test.cpp -o alignof_test && ./alignof_test
Run Code Online (Sandbox Code Playgroud)

输出:

foo sizeof: 8 alignof: 64
bar sizeof: 8 alignof: 8
baz sizeof: 8 alignof: 8
Run Code Online (Sandbox Code Playgroud)

所以严格来说,不,但上面的论点re:数组必须保留.

  • [`错误:数组元素的对齐大于元素大小`](https://ideone.com/hKCQKy),所以你不能创建这些数组.我想知道这是否是严格符合的行为. (3认同)
  • `__attribute__`是GCC扩展名.我没有找到一种方法来获得与`alignof`相同的结果; 我可以使用`alignof(obj)> sizeof(obj)`创建一个对象,但不能创建一个类型. (3认同)
  • `__attribute__((aligned))`是标准的C ++吗?你可以用“ alignof”做同样的把戏吗? (2认同)

Dan*_*man 8

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

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

alignof定义是(见5.3.6 expr.alignof):

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

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

typedef uint32_t __attribute__ ((aligned (64))) aligned_uint32_t;
std::cout << sizeof(aligned_uint32_t) << " -> " << alignof(aligned_uint32_t);
// Output: 4 -> 64
Run Code Online (Sandbox Code Playgroud)

编辑

正如其他人所指出的那样,这些类型不能在数组中使用,例如尝试编译以下内容:

aligned_uint32_t arr[2];
Run Code Online (Sandbox Code Playgroud)

结果是 error: alignment of array elements is greater than element size

由于数组要求指定的类型符合条件: sizeof(T) >= alignof(T)


o11*_*11c 7

许多编译器允许大小的数组0.对齐保持与鞋底元件的对齐相同.

(除此之外,这对于在不能使用位域的情况下强制执行特定对齐非常有用)

  • 哦,是的,0长度数组是一些编译器上的东西.有大量0螺丝的类型有很多东西. (2认同)