define
文は次 のとおりです。
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
目的はビットアライメントだと言われました。
それがどのように機能するのだろうか、前もってthx。
上記のマクロは、 のサイズをn
最も近い、それ以上のsizeof(int)
境界に揃えるだけです。
a
値を最も近い以上の任意の境界b
に揃えるための基本的なアルゴリズムは、次のとおりです。
a
をb
切り上げて割り、b
商を再度掛けます。符号なし (または正の値のみ) の領域では、最初のステップは次の一般的なトリックによって達成されます。
q = (a + b - 1) / b
// where `/` is ordinary C-style integer division (rounding down)
// Now `q` is `a` divided by `b` rounded up
これを 2 番目のステップと組み合わせると、次のようになります。
aligned_a = (a + b - 1) / b * b
aligned_a
目的の整列値を取得します。
このアルゴリズムを目前の問題に適用すると、次の_INTSIZEOF
マクロの実装に到達します。
#define _INTSIZEOF(n)\
( (sizeof(n) + sizeof(int) - 1) / sizeof(int) * sizeof(int) )
もうこれで十分です。
ただし、アラインメント境界が 2 の累乗であることが事前にわかっている場合は、除算と乗算のシーケンスを単純なビット演算に置き換えることで、計算を「最適化」できます。
aligned_a = (a + b - 1) & ~(b - 1)
これはまさに、上記の_INTSIZEOF
マクロの元の実装で行われていることです。
この「最適化」は、一部のコンパイラーではおそらく意味があるかもしれません (ただし、最新のコンパイラーはそれ自体でそれを理解できると思います)。ただし、上記の_INTSIZEOF(n)
マクロが明らかにコンパイル時の式として機能することを意図していることを考慮すると (VLA オブジェクト/型が として渡されない限り、実行時の値には依存しませんn
)、そのように最適化する意味はあまりありません。
ヒントは次のとおりです。
一般的な方法ceil(a/b)
は次のとおりです。
(a + (b-1)) / b