Мне интересно, как использовать условные обозначения для указателей/массивов типа С++. Вот пример использования, который у меня есть на данный момент:
Вычислите простую 32-битную контрольную сумму над двоичным блоком данных, рассматривая его как массив из 32-битных целых чисел (мы знаем, что его общая длина кратна 4), а затем суммируя все значения и игнорируя переполнение.
Я бы ожидал, что такая функция будет выглядеть так:
uint32_t compute_checksum(const char *data, size_t size)
{
const uint32_t *udata = /* ??? */;
uint32_t checksum = 0;
for (size_t i = 0; i != size / 4; ++i)
checksum += udata[i];
return udata;
}
Теперь у меня есть вопрос, что вы считаете "лучшим" способом преобразования data
в udata
?
C-стиль?
udata = (const uint32_t *)data
С++ cast, который предполагает, что все указатели являются конвертируемыми?
udata = reinterpret_cast<const uint32_t *>(data)
С++ задает то, что между произвольными типами указателей, используя промежуточный void*
?
udata = static_cast<const uint32_t *>(static_cast<const void *>(data))
Передача через объединение?
union {
const uint32_t *udata;
const char *cdata;
};
cdata = data;
// now use udata
Я полностью понимаю, что это не будет 100% -ным портативным решением, но я только ожидаю использовать его на небольшом наборе платформ, где я знаю, что он работает (а именно, недопустимые обращения к памяти и предположения компилятора на сглаживание указателя). Что бы вы порекомендовали?