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

时间:2017-09-27 21:23:28

标签: c++ c++11 memory-alignment alignof

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

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

struct small {
  char c;
};

高于正常情况,它们的“大小”也会向上调整,以便阵列中对象之间的关系在保持对齐时是有意义的(至少在我的testing中。例如:

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

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

4 个答案:

答案 0 :(得分:30)

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

Foo arr[2];

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

正如Zalman Stern's example所示,至少有一些编译器允许您声明一个对齐大于其大小的类型,结果是编译器根本不允许您声明该类型的数组。这不符合标准的C ++(它使用类型属性,are a GCC extension),但这意味着您可以在实践中使用alignof(T) > sizeof(T)

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

答案 1 :(得分:12)

->leftJoin('event_odds AS eo1', function($q) use($win_market, $home_market_value) {
    $q->on('events.id', '=', 'eo1.event_id')
      ->where('eo1.market_id', '=', $win_market->id)
      ->where('eo1.market_value_id', '=', $home_market_value->id)
      ->on('eo1.value', '=', 'eo1.best_odd');
})

编译:

#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

严格来说,不,但上面的论点是:数组必须保留。

答案 2 :(得分:8)

根据引入alignof运算符的c++ 11 standardsizeof定义如下(参见5.3.3 expr.sizeof):

  

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

<强>被修改

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

aligned_uint32_t arr[2];

error: alignment of array elements is greater than element size

中的结果

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

答案 3 :(得分:7)

许多编译器允许大小为0的数组。对齐方式与鞋底元素的对齐方式保持一致。

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