Является ли sizeof (int) равным sizeof (void *)? - PullRequest
4 голосов
/ 18 января 2012

Всегда ли размер типа данных "int" всегда равен размеру указателя на языке c?

Мне просто любопытно.

Ответы [ 7 ]

8 голосов
/ 18 января 2012

Совсем нет, нет гарантии, что sizeof(int) == sizeof(void*).А в Linux / AMD64 sizeof(int) составляет 4 байта, а sizeof(void*) составляет 8 байтов (аналогично sizeof(long) на этой платформе).

Последний стандарт C (например, C99) определяет стандартный заголовок <stdint.h>который должен определять, среди прочего, целочисленный тип intptr_t, который гарантированно будет иметь размер указателей (и, возможно, даже который обратимо преобразуется в и из указателей).

Я думаю, что стандарт не гарантируетчто все указатели имеют одинаковый размер, в частности указатель на функции может быть «больше», чем указатели данных (я не могу назвать платформу, где это правда).Я считаю, что недавний стандарт Posix требует этого (например, для dlsym).

2 голосов
/ 18 января 2012

Это не гарантируется.

И, например, в большинстве 64-битных систем оба размера обычно отличаются.

Даже sizeof (int *) не гарантируется равным sizeof (void *)

Единственная гарантия для void * размера

sizeof (void *) == sizeof (char *)
   == sizeof (signed char *) == sizeof (unsigned char *)
2 голосов
/ 18 января 2012

Нет.например, в большинстве 64-битных систем int равно 4 байта, а void * равно 8.

1 голос
/ 18 января 2012

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

6.2.5 Типы
...
27 Указатель на void должен иметь те же требования к представлению и выравниванию, что и указатель на тип символа. 39) Аналогично, указатели на квалифицированные или неквалифицированные версии совместимых типов должны иметь одинаковые требования к представлению и выравниванию. Все указатели на типы конструкций должны иметь одинаковые требования к представлению и выравниванию. как друг друга. Все указатели на типы объединения должны иметь одинаковое представление и требования выравнивания как друг друга. Указатели на другие типы не обязательно должны иметь одинаковые Требования к представлению или выравниванию.
...
39) Те же требования к представлению и выравниванию подразумевают взаимозаменяемость, как аргументы функций, возвращаемые значения из функций и членов объединений.
...
6.3.2.3. Указатели
...
5 Целое число может быть преобразовано в любой тип указателя. За исключением случаев, указанных ранее, результат определяется реализацией, может быть неправильно выровнен, может не указывать на объект ссылочного типа и может быть представлением прерываний. 56)

6 Любой тип указателя может быть преобразован в целочисленный тип. За исключением случаев, указанных ранее, результат определяется реализацией. Если результат не может быть представлен в целочисленном типе, поведение не определено. Результат не обязательно должен находиться в диапазоне значений любого целого числа тип.
...
56) Функции отображения для преобразования указателя в целое число или целое число в указатель предназначены для соответствовать структуре адресации среды выполнения.
1 голос
/ 18 января 2012

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

С учетом сказанного, в реальном мире, если вы не имеете дело с действительно неясными устаревшими 16-битными системами или странными DSP или чем-то подобным, sizeof(int) будет меньше или равен sizeof(void *), и вы можете добросовестно преобразуйте значения int в void *, чтобы передать их интерфейсам (например, pthread_create), которые принимают общий аргумент void *, чтобы избежать расточительного распределения и освобождения памяти для хранения одного int. В частности, если вы уже используете интерфейсы POSIX или Windows, это определенно безопасное реальное предположение.

Вы должны никогда предполагать, что void * может быть точно представлено в int (т.е. приведение указателя на int и обратно). Это не работает ни на каких популярных реальных 64-битных системах, и процент систем, на которых он работает, в ближайшем будущем резко упадет.

1 голос
/ 18 января 2012

Языки C не дают никаких гарантий, когда дело доходит до целочисленных значений или размеров указателей.

Размер int обычно такой же, как ширина шины данных , но не обязательно. Размер указателя обычно совпадает с шириной адресной шины , но не обязательно.

Многие компиляторы используют нестандартные расширения, такие как ключевое слово far, для доступа к данным, превышающим ширину типа указателя по умолчанию.

В дополнение к 64-битным системам существует также множество микроконтроллерных / микропроцессорных архитектур, в которых размер int и размер указателя различны. Windows 3.1 и DOS являются другими примерами.

1 голос
/ 18 января 2012

Нет.Некоторый (в основном более старый, эпоха VAX) код предполагает это, но он определенно не требуется, и предполагается, что он не переносим.Существуют реальные реализации, в которых они различаются (например, в некоторых современных 64-разрядных средах используется 64-разрядный указатель и 32-разрядный тип int).

...