Этот расчет обеспечивает соответствие адреса указанному количеству (которое должно быть степенью 2). Это означает, что младшие n
биты должны быть равны нулю, когда выравнивание равно 2^n
.
Давайте сделаем это в двоичном виде. Предположим, мы получили случайный указатель, выровненный на 16 байтов, в то время как мы хотим, чтобы он был выровнен на 64 байта, и вычислили. (Это предполагает два дополнения, что, кстати, не гарантируется, но является стандартом де-факто):
address = ...1101010000
address - 1 -> ...1101001111
address + 64 -> ...1110001111
-alignment -> ...1111000000
address & -alignment -> ...1110000000
Таким образом, в действительности он находит наименьшее значение, которое делится на выравнивание из-за того, что -alignment
имеет все биты ноль ниже точки выравнивания. Он также гарантирует, что он больше, чем исходный указатель, добавив alignment-1
, который является отрицанием -alignment
в качестве битов, то есть все старшие биты равны нулю, а младшие - единица.
Что если адрес уже выровнен? Затем в результате вычисления получается исходный указатель, поскольку у него младшие биты равны нулю, все младшие биты равны единице, а затем их И.