Все ли указатели данных одинакового размера на одной платформе для всех типов данных?

Являются ли char*, int*, long* или даже long long* того же размера (на данной платформе)?

Ответ 1

У них не гарантируется одинаковый размер, хотя на платформах у меня есть опыт работы с ними, как обычно.

C 2011 онлайн-проект:

6.2.5 Типы
...
28     Указатель на void должен иметь те же требования к представлению и выравниванию, что и указатель на тип символа. 48) Аналогично, указатели на квалифицированные или неквалифицированные версии совместимые типы должны иметь одинаковые требования к представлению и выравниванию. Все указатели на типы структуры должны иметь одинаковые требования к представлению и выравниванию как друг друга. Все указатели на типы профсоюзов должны иметь одинаковое представление и согласования требований друг с другом. Указатели на другие типы не должны иметь одинаковые представления или согласования.
48). Те же требования к представлению и выравниванию подразумевают взаимозаменяемость как аргументы функции, возвращаемые значения из функций и члены объединений.

Ответ 2

Не обязательно. Стандарт не гарантирует sizeof(double*) == sizeof(int*). Например, предположим, что процессор с двумя адресными шинами различной ширины (например, на некоторых процессорах архитектуры Harvard) может иметь указатели разных размеров.

Ответ 3

В 16-разрядных встроенных процессорах, у которых есть оцифрованные (или выгруженные) ОЗУ и/или флэш-память, использование страниц может привести к тому, что указатели будут разных размеров, хотя это не зависит от размера данных, на которые они указывают.

Например, на процессоре Freescale HCS12, у которого есть флеш-память, указатели данных - все 16 бит.

Однако указатели на функции - 16 бит для ближайших указателей (для кода на той же странице, что и вызывающая функция, или в небанковской вспышке), или 24 бита для дальних указателей (для кода на другой странице), включая номер страницы в адресе.

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

Можно предположить, что 16-разрядный процессор с банковским ОЗУ также имел бы разные размеры для ближних и дальних указателей данных.

Ответ 4

Обратите внимание на то, что говорит стандарт C - как цитирует Джон Боде. Обратите также внимание на то, что стандарт C ничего не говорит о размерах указателей на функции.

Стандарт POSIX устанавливает некоторые дополнительные требования:

2.12.3 Типы указателей

Все типы указателей функций должны иметь то же представление, что и указатель типа на void. Преобразование указателя функции в void * не должно изменять представление. Значение void *, возникающее в результате такого преобразования, может быть преобразовано обратно в исходный тип указателя функции с использованием явного приведения без потери информации.

Примечание. Стандарт ISO C не требует этого, но он необходим для соответствия POSIX.

Ответ 5

Нет такой гарантии ни в стандартах ISO, ни в С++, но на практике я еще не видел платформу, на которой это не выполняется.

Обратите внимание, что независимо от этого, reinterpret_cast 'один указатель на другой чаще всего приведет к U.B., за некоторыми исключениями (void* и unsigned char* для POD). Так что любые профсоюзные трюки. Итак, очевидный вопрос: зачем вам это важно?

Ответ 6

При программировании реального режима x86 с Watcom C у вас может быть смешанная модель памяти, использующая 16-разрядные ближние указатели и 32-разрядные указатели.

Ответ 7

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

Ответ 8

Как правило, да, все указатели на что-либо, указывают ли они на int или long или строку или массив строк или функцию, указывают на один адрес памяти, который имеет одинаковый размер на машине. Это связано с тем, что Процессор на машине имеет адресный регистр, в который загружаются эти указатели, и размер этого регистра адресов контролирует размер указателей.

Единственное исключение может быть в таких случаях, как старые 16-разрядные компьютеры Intel 8088, где для определения адреса памяти использовался двухступенчатый процесс с использованием 16-разрядного указателя сегмента (который идентифицировал 64-килобайтный блок памяти в адресе 1 Мбайт пространство), а затем второй 16-разрядный адрес памяти для идентификации конкретного адреса памяти в этом сегменте. Эти два 16-разрядных адреса были объединены для получения полного 20-битного адреса памяти. В этом случае я предполагаю, что может быть возможным различие между отдельными 16-разрядными адресами и комбинированным 20-битным адресом.