2015-11-23 3 views
11

В this answer, int8_t* используется для (байт) арифметики указателей:C++ offsetof полукокса * арифметической

std::size_t offset = offsetof(Thing, b); 
Thing* thing = reinterpret_cast<Thing*>(reinterpret_cast<int8_t*>(ptr) - offset); 

Я всегда использовал в прошлом char* но комментарии действительно сбивает с толку, и никто не ответил, так что я разместил этот отдельный вопрос.

Действительно ли char* действительный и предпочтительный способ выполнения этих расчетов?

ответ

2

Вы обязательно использование char*: поведение на использовании reinterpret_cast с int8_t* на указатель на то, что не является int8_tявляется неопределенным. Кастинг до char* можно рассматривать как исключение из правила.

Pre C++ 14, char может быть 1-го типа дополнения с диапазоном от -127 до +127. int8_t должно быть дополнением 2. Даже C++ 14 и далее, я не могу понять, почему типы связаны: char все равно может быть либо подписанным, либо беззнаковым типом.

+0

Что касается размеров указателей, я думал, что все указатели на объекты имеют одинаковый размер в C++. Это не гарантировано? Но независимо от ответа на арифметику указателя влияет 'sizeof (T)', а не 'sizeof (T *)'. Во всяком случае, стоит упомянуть о псевдониме. –

+0

Ваш последний вопрос верен: sizeof (*) не имеет значения, поэтому я удалил его, так как он только ослабляет ответ. Что касается вашего первого момента, я не понимаю, почему уместны указатели на объекты. У нас есть только POD. – Bathsheba

+1

Ни один из первых абзацев не является истинным. 'uint8_t' действительно не является частью специального разрешения в правиле строгого aliasing, но указатель не используется для ввода типа здесь, только для арифметики указателя. Правила для арифметики указателей являются скорее более разрешительными и требуют только того, чтобы выравнивание было подходящим, и арифметика не выводит вас за пределы одного и того же полного объекта .... и специальных ограничений для 'char *' нет. –

Смежные вопросы