Должен ли я привести size_t к ptrdiff_t?

У меня есть массив указателей malloc, который формирует хэш-таблицу. Чтобы пройти по хеш-таблице, я бы использовал арифметику указателей, например:

node_t ** tc = table;
size_t tcs = sizeof(node_t *);
for(long i = 0; i < tableSize; tc+=tcs, ++i) { 
    // Do some stuff with *tcs location in the table.
}

Вопрос в том, должен ли я сыграть size_t вернулся sizeof() в ptrdiff_t для правильного добавления в инкрементной части for состояние? или это вообще имеет значение для дополнения?

3 ответа

Решение

Нет необходимости ptrdiff_t здесь, как нет разницы между указателями.

Что вы, вероятно, хотите, это:

for (node_t ** tc = table; tc < (table + tableSize); ++tc) {
  ...
}

Тебе нужно ptrdiff_t для обработки отрицательных значений. size_t обрабатывает положительные значения, такие как результат sizeof в вашем примере, поэтому вам не нужен актерский состав.

При этом код выглядит подозрительно: компилятор C учитывает размер struct в вашу арифметику указателя, поэтому тот факт, что вы должны добавить sizeof(node_t*) на двойной указатель на node_t вероятно ошибка Если вы хотите перейти к следующему указателю в массиве указателей, добавьте 1 к текущему значению этого указателя. Компилятор достаточно умен, чтобы умножить это 1 от sizeof(*ptr) для вас, исходя из типа указателя.

Нет, тебе не нужно

Арифметика указателя выполняется в зависимости от типа указателя T *, Добавление size_t не повлияет на арифметику указателя, поскольку приращение выполняется с помощью sizeof(T),

Чтобы процитировать стандарт (проект C11):

6.5.6 Аддитивные операторы

Когда выражение с целочисленным типом добавляется или вычитается из указателя, результат имеет тип операнда указателя. Если операнд-указатель указывает на элемент объекта массива, а массив достаточно велик, результат указывает на смещение элемента от исходного элемента, так что разность индексов полученного и исходного элементов массива равна целочисленному выражению. Другими словами, если выражение P указывает на i-й элемент объекта массива, выражения (P)+N (эквивалентно, N+(P)) и (P)-N (где N имеет значение n) указывают соответственно i+n-м и i-n-м элементам массива, если они существуют. Более того, если выражение P указывает на последний элемент объекта массива, выражение (P)+1 указывает один за последним элементом объекта массива, а если выражение Q указывает на один последний элемент последнего элемента массива, выражение (Q)-1 указывает на последний элемент объекта массива. Если и операнд-указатель, и результат указывают на элементы одного и того же объекта массива или один после последнего элемента объекта массива, оценка не должна вызывать переполнение; в противном случае поведение не определено. Если результат указывает на один последний элемент массива, он не должен использоваться в качестве операнда оцениваемого унарного оператора *.

С другой стороны, кастинг size_t в ptrdiff_t может привести неверный код как ptrdiff_t это подписанное время size_t это тип без знака. Так что, если результирующее значение больше, чем что ptrdiff_t может держать, тогда есть проблема. Короче говоря, арифметика указателей хорошо определена при добавлении любого целочисленного типа к типу указателя, и вам вообще не нужно такое приведение.

Другие вопросы по тегам