Из ANSI-ISO-IEC 14882-2003, стр.87 (c ++ 03):
"75) Еще один способ приблизиться к указателю
арифметика является первым, чтобы преобразовать
указатель (и) на символьный указатель (и): В
эта схема интегральное значение
выражение добавляется или вычитается из
преобразованный указатель является первым
умножается на размер объекта
первоначально указывало на
результирующий указатель преобразуется обратно в
оригинальный тип. Для указателя
вычитание, результат
разница между персонажем
указатели также делятся на
размер объекта изначально указан
к ".
Это говорит о том, что разница указателей равна размеру объекта.
Если мы уберем UB'ness из приращения указателя на скаляр a и превратим a в массив:
int a[1];
size_t size_of_int = (char*)(a+1) - (char*)(a);
std::cout<<size_of_int;// or printf("%zu",size_of_int);
Тогда это выглядит хорошо. Положения о требованиях к выравниванию соответствуют сноске, если требования по выравниванию всегда делятся на размер объекта.
ОБНОВЛЕНИЕ: Интересно. Как многие из вас, вероятно, знают, GCC позволяет указывать явное выравнивание типов в качестве расширения. Но я не могу сломать метод OP "sizeof" с ним, потому что GCC отказывается компилировать его:
#include <stdio.h>
typedef int a8_int __attribute__((aligned(8)));
int main()
{
a8_int v[2];
printf("=>%d\n",((char*)&v[1]-(char*)&v[0]));
}
Сообщение error: alignment of array elements is greater than element size
.