Я всегда думал, что для адресной математики не важно, какого типа указатель - все равно вычисления будет производить в байтах. Но, кажется, я упустил что-то:
int main()
{
int a=5;
void *pa = &a;
cout << pa << endl;
void *ppa = pa + 12;
cout << ppa << endl;
void *sza = (size_t*)pa + 12;
cout << sza << endl;
}
Результаты разные в gcc:
22ff00
22ff0c
22ff30
Я не понимаю, почему адрес указателя sza отличается от адреса ppa. Ведь в обоих случаях я прибавил к pa 12 байт. Почему так?
Вообще, арифметика на типах void* запрещена в стандарте. Так что надо приводить к какому-то конкретному типу указателя, а не обобщённому void*. В gcc используется своё расширение (послабление), позволяющее интерпретировать void* как char*, т.е. выполнять единичный сдвиг (sizeof(char) == 1).
А когда будет уже этот конкретный тип, то арифметика будет на него и опираться, т.е. смещать адрес на указанное кол-во элементов соответствующего типа. Т.е. 12 - это не 12 байт, а 12 раз по sizeof(*тип указателя), для которого производится арифметическая операция. В последнем случае sizeof(size_t), что будет 4 или 8 в зависимости от разрядности системы (32 или 64 бит соответственно).
Продвижение своими сайтами как стратегия роста и независимости