С помощью функции есть какой-либо законный способ интерпретировать параметр char *
заданной длины как указатель другого целочисленного типа, а затем обратиться к указанному преобразованному указателю? Там, кажется, много незаконных (UB) способов сделать это ...Любой законный способ переосмыслить char * как массив другого примитивного типа для операций только для чтения?
К примеру, учитывая следующий прототип функции:
int32_t sum_32(char *a, int len);
Я хотел бы знать, если есть способ писать что-то функционально эквивалентное следующий код, по закону:
int32_t sum_32(char *a, int len) {
assert(len % 4 == 0);
int32_t total = 0;
for (int i = 0; i < len/4; i++) {
total += ((int32_t *)a)[i];
}
return total;
}
конечно, один из способов сделать это просто, чтобы сломать доступы в доступ символов размера со смещением рекомбинировать в большее значение (с некоторым предположением о е ndianness, вот если предположить LE):
int32_t sum_32(char *a, int len) {
assert(len % 4 == 0);
int32_t total = 0;
for (int i = 0; i < len; i += 4) {
int32_t val = (int32_t)
(a[i+0] << 0) +
(a[i+1] << 8) +
(a[i+2] << 16) +
(a[i+3] << 24) ;
total += val;
}
return total;
}
... но здесь я ищу решение, которые имеют доступ к основному массиву один int32_t
в то время.
Если ответ «это не возможно», не изменится ответ, если я знаю, что источник char *a
является функцией распределения - или, в более широком смысле, есть ли какие-либо дополнительные ограничения, я могу поставить на a
таким образом, что доступ к нему как более крупный тип является законным?
Первой проблемой является, вероятно, выравнивание. Если это происходит из функции распределения, вы, по крайней мере, знаете, что это правильно выравнивание. – melpomene
Я предлагаю вам взглянуть на реализацию GNU stdlib. Строковые функции содержат много такого рода обработки слова в момент времени. (после выравнивания, конечно, заботятся) – wildplasser
Как вы уже писали, вам нужно заботиться о выравнивании и энсианности. Например, [этот ответ] (http://stackoverflow.com/a/4840428/69809) имеет несколько функций для округления адреса указателя по модулю 4 или 8. Если вам нужно обрабатывать разные endianess, то вы также можете работать с отдельными байтами. Поскольку это помечено как «производительность», вы уверены, что не слишком быстро оптимизируете? Последняя функция не имеет никакого сдвига, кстати. – Groo