переменные типа size_t и ptrdiff_t - PullRequest
20 голосов
/ 31 октября 2011

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

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

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

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

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

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

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

ДОБАВЛЕНО: Я хочу иметь возможность использовать отрицательные смещения.И какая разница в использовании uintptr_t и intptr_t?

Ответы [ 3 ]

19 голосов
/ 31 октября 2011

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);

В C ++:

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 или C ++; он определяется Posix как тип аргументов некоторых функций и возвращаемых значений. Лучше всего использовать ptrdiff_t, за исключением случаев, когда речь идет непосредственно о функциях Posix.

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

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

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

1 голос
/ 01 ноября 2011

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

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

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

0 голосов
/ 31 октября 2011

Предполагается, что _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)

...