Большинство компиляторов микрокомпьютера C имеют два знаковых целочисленных типа с одинаковым размером и представлением вместе с двумя такими неподписанными типами. Если int
- 16 бит, его представление будет в целом соответствовать short
; если long
- 64 бита, он будет в целом соответствовать long long
; в противном случае int
и long
обычно будут иметь сопоставимые 32-битные представления.
Если на платформе, где long
, long long
и int64_t
имеют одинаковое представление, необходимо передать буфер в три функции API по порядку (предположим, что API-интерфейсы находятся под контролем кого-то другого и используют указанные типы, если функции могут быть легко изменены, их можно просто изменить, чтобы использовать один и тот же тип).
void fill_array(long *dat, int size);
void munge_array(int64_t *dat, int size);
void output_array(long long *dat, int size);
существует ли какой-либо эффективный стандартно-совместимый способ разрешить все три
функции использовать один и тот же буфер, не требуя, чтобы все данные
скопировать между вызовами функций? Я сомневаюсь, что авторы правил сглаживания C предполагали, что такая вещь должна быть сложной, но для современных компиляторов модно считать, что ничего, написанное через long*
, не будет прочитано через long long*
, даже если эти типы имеют одинаковые представление. Кроме того, в то время как int64_t
обычно будет таким же, как либо long
, либо long long
, реализации не соответствуют друг другу.
В компиляторах, которые не агрессивно используют псевдонимы на основе типов через вызовы функций, можно просто наложить указатели на соответствующие типы, возможно, включая статическое утверждение, чтобы гарантировать, что все типы имеют одинаковый размер. Проблема заключается в том, что если компилятор вроде gcc после разворачивания вызовов функций видит, что какое-то хранилище записывается как long
, а затем читается как long
, без каких-либо промежуточных записей типа long
, оно может заменить более позднее чтение со значением, записанным как тип long
, даже если были промежуточные записи типа long long
.
Отключение псевдонимов на основе типов - это, конечно, один из подходов к созданию такая работа кода. Любой достойный компилятор должен это допускать, и он избежит многих другие возможные ловушки. Тем не менее, похоже, что должен быть стандарт- определенный способ эффективного выполнения такой задачи. Есть?