Подтвердить что ты не робот

Переменные типа size_t и ptrdiff_t

Прочитав сообщения, связанные с size_t и ptrdiff_t, я хочу подтвердить следующее:

  • если максимальный размер массива меньше 1/2*(max number represent-able by size_t), я могу безопасно использовать ptrdiff_t и проверить относительные расстояния между двумя указателями на один и тот же объект? (Поскольку я говорил о массиве, "указатели к тому же объекту" означает "указатели на один и тот же массив" ).

  • если я хочу объявить переменную, которая может представлять смещение от другого указателя, я лучше объявляю его как тип ptrdiff_t?

  • Как вывести переменные типа size_t и ptrdiff_t в C и С++? Правильно ли следующее: Строка формата кросс-платформенной для переменных типа size_t?

  • is uintptr_t - это просто другое имя для size_t ИЛИ оно должно использоваться как отдельный тип из size_t?

  • есть ssize_t и intptr_t другие имена для ptrdiff_t ИЛИ его нужно использовать по-другому?

Я начинаю использовать gcc на Ubuntu. Я просто узнал об этих типах при использовании кого-то else.

ADDed: Я хочу иметь возможность использовать смещения отрицательные. И любая разница в использовании uintptr_t и intptr_t?

4b9b3361

Ответ 1

1: если максимальный размер массива меньше 1/2 * (максимальное число может быть представлено size_t), я могу безопасно использовать ptrdiff_t и проверять относительные расстояния между двумя указателями на один и тот же объект

Это будет так, если sizeof(size_t) <= sizeof(prtdiff_t). Это будет иметь место в разумной реализации, но нет гарантии.

2: если я хочу объявить переменную, которая может представлять смещение от другого указателя, я лучше объявляю его как тип ptrdiff_t?

Да, для этого предназначен тип.

3: Как вывести переменные типа size_t и ptrdiff_t в C и С++?

В C:

printf("%zu %td\n", size, ptrdiff);

В С++:

std::cout << size << ' ' << ptrdiff << '\n';

4: is uintptr_t - это просто другое имя для size_t ИЛИ оно должно использоваться как отдельный тип из size_t?

Его следует рассматривать как отдельный тип. uintptr_t - целочисленный тип, который может содержать любое значение указателя, преобразованное в целое число; он может не существовать на некоторых платформах.

5: есть ssize_t и intptr_t имя пыльника для ptrdiff_t ИЛИ его нужно использовать по-другому?

ssize_t не является стандартным типом в отношении языков C или С++; он определяется Posix как тип некоторых аргументов функции и возвращаемых значений. Лучше было бы использовать ptrdiff_t, кроме случаев прямого взаимодействия с функциями Posix.

intptr_t предназначен для хранения целочисленного представления указателя, а не разницы между указателями. На некоторых платформах они могут иметь разные размеры, а intptr_t может вообще не определяться, поэтому их нельзя использовать взаимозаменяемо.

Я хочу иметь возможность использовать отрицательные смещения. И любая разница в использовании uintptr_t и intptr_t?

Не используйте ни один из этих типов для представления смещений; используйте ptrdiff_t. Используйте эти типы в особых обстоятельствах, когда вы хотите по какой-либо причине конвертировать указатели в их целые представления.

Ответ 2

uintptr_t и intptr_t достаточно велики, чтобы удерживать любое значение указателя void* без потери информации. Они должны иметь возможность однозначно представлять адрес любого объекта в вашем программном адресном пространстве - включая любой байт внутри любого объекта.

size_t - тип, предоставляемый оператором sizeof; ptrdiff_t - это тип, полученный путем вычитания двух указателей. Они должны быть достаточно большими для одного объекта. (И возможно иметь такой большой объект, что вычитание двух указателей, указывающих на противоположные концы, будет переполняться.)

Большинство современных систем имеют одно монолитное адресное пространство, но C предназначен для работы с системами, которые этого не делают. Например, в некоторых системах наибольший возможный объект может представлять собой небольшую часть размера всего адресного пространства, а сравнение или вычитание указателей на отдельные объекты может быть бессмысленным. (Подумайте о сегментированной схеме адресации, где вычитание указателя и сравнение учитывают только смещение части адреса.)

Ответ 3

Предполагая, что _ptrdiff_t_ является опечаткой:

1) Да. Если максимальный размер массива меньше SIZE_MAX/2, вы можете безопасно использовать ptrdiff_t
2) Иногда: ptrdiff_t обычно является различием между двумя указателями, тогда как size_t является смещением. Важное значение здесь size_t всегда положительно, ptrdiff_t может быть отрицательным. Обратите внимание, что на некоторых платформах они могут быть совершенно разных размеров. 3) Вы выводите переменные типа size_t и ptrdiff_t так же, как вы выводите любой другой тип переменной.

size_t a = 10;
ptrdiff_t b = 20;
printf("%u %d", ((unsigned int)a), ((int)b));
std::cout << a << b;

4) uintptr_t представляет собой целое число без знака, по крайней мере такое же большое, как int*, чтобы безопасно разрешить целочисленную математику по указателям. size_t не может быть таким же, насколько я могу судить.
5) ssize_t - нестандартный тип C, соответствующий ptrdiff_t. Вместо этого используйте ptrdiff_t. (On platforms supporting the POSIX 1003.1-1996 API standard, which includes most Unix-like systems, a signed variant of size_t named ssize_t is available, which was not part of the ANSI or ISO C standards.http://en.wikipedia.org/wiki/Size_t)