Уместно ли использовать off_t для небайтных смещений?

Предположим, я пишу функцию, которая принимает float a[] и смещение, в этот массив, и возвращает элемент с этим смещением. Разумно ли использовать подпись

float foo(float* a, off_t offset);

для этого? Или off_t относится только к смещениям в байтах, а не к арифметике указателей с размерами элементов aribtrary? то есть разумно ли сказать a[offset] когда смещение имеет тип off_t?

Справочное руководство по библиотеке GNU C гласит:

off_t
This is a signed integer type used to represent file sizes.

но это не говорит мне много.

Моя интуиция заключается в том, что ответ «нет», поскольку фактический адрес, используемый в [offset], является адресом смещения + sizeof (float) *, поэтому «sizeof (float) * offset» является off_tи sizeof (float) является size_tи оба являются константами с «измерениями».

Замечания: Смещение может быть отрицательным.

0

Решение

Есть ли веская причина, почему вы просто не используете int? Это
тип по умолчанию для целочисленных значений в C ++ и должен использоваться
если нет веских причин не делать этого.

Конечно, одной из причин может быть переполнение. Если
контекст таков, что вы можете получить очень большой
массивы, вы можете использовать ptrdiff_t, который определяется (в
C и C ++) как тип, полученный в результате вычитания двух
указатели: другими словами, это гарантированно не переполняется (когда
используется как смещение) для всех типов с размером больше 1.

2

Другие решения

Вы могли бы использовать size_t или же ptrdiff_t как тип индекса (ваш второй параметр — это больше индекс внутри массива с плавающей точкой, чем смещение).

Ваше использование — это индекс, а не смещение. Обратите внимание, что стандарт offsetof макрос определен для возврата байтовых смещений!

На практике вы могли бы даже использовать int или же unsigned, если вы не верите, что ваш массив может содержать миллиарды компонентов.

Вы можете захотеть #include <stdint.h> (или же <cstdint> с недавним C ++) и имеют явно определенные размеры, такие как int32_t для ваших индексов.

По причинам читабельности источника вы можете определить

  typedef unsigned index_t;

и позже используйте его, например

  float foo(float a[], index_t i);

Мое мнение, что вы просто должны использовать int как тип ваших индексов. (но обрабатывать внешние индексы соответственно).

2

Я бы сказал, что это не подходит, так как

  1. off_t используется (предназначен для) для представления размеров файлов
  2. off_t это подписанный тип.

Я бы пошел на size_type (обычно это имя типа typedef для size_t), который используется стандартными контейнерами.

1

Возможно, ответ заключается в использовании ptrdiff_t? Это…

  • может быть отрицательным;
  • указывает на разницу не в байтах, а в единицах произвольного размера в зависимости от типа элемента.

Как вы думаете?

0
По вопросам рекламы [email protected]