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

Почему размер указателя составляет 4 байта в С++

На 32-битной машине, почему размер указателя 32-бит? Почему не 16-битный или 64-битный? Какие минусы и плюсы?

4b9b3361

Ответ 1

Потому что он имитирует размер фактических "указателей" в ассемблере. На машине с 64-разрядной адресной шиной она будет 64 бит. В старых 6502 это была 8-разрядная машина, но у нее была 16-разрядная адресная шина, чтобы она могла адресовать 64 КБ памяти. На большинстве 32-битных машинах было достаточно 32 бит для адресации всей памяти, так что размер указателя был на С++. Я знаю, что некоторые из ранних чипов серии M68000 имели только 24-битное адресное пространство памяти, но оно было адресовано из 32-битного регистра, поэтому даже на тех, у которых указатель будет 32 бита.

В плохие старые дни 80286 было хуже - существовал 16-разрядный адресный регистр и 16-разрядный сегментный регистр. Некоторые компиляторы С++ не скрывали это от вас и заставили вас объявить ваши указатели как near или far в зависимости от того, хотите ли вы изменить регистр сегментов. К счастью, я переработал большинство этих клеток мозга, поэтому я забыл, что указатели near были 16 бит, но на уровне машины они были бы.

Ответ 2

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

Если на вашей реализации указатель 32-битный, то это, скорее всего, архитектура, которая может адресовать 2 ^ 32 байта. (Обратите внимание, что даже размер байтов может отличаться в зависимости от реализации.) 64-битные архитектуры обычно могут адресовать 2 ^ 64 байта, поэтому реализации на этих архитектурах, скорее всего, будут иметь размер указателя 64 бит.

Ответ 3

16 бит, очевидно, будет недостаточным - вы могли бы только адресовать 64K.

Почему бы не эмулировать 64-битную систему на 32-битных системах - я думаю, потому что производительность арифметики указателя ухудшится.

Ответ 4

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

Однако следует также отметить, что даже в одной реализации разные типы указателей могут иметь разные размеры. В частности, типы указателя на элемент (которые я дам - ​​указатели с нечетным шаром) могут иметь разные размеры, чем простые указатели на объекты.

То же самое касается указателей на простые старые функции - они могут иметь разный размер, чем указатели на объекты (это относится как к C, так и к С++). Однако на современных настольных системах вы обычно обнаружите, что указатели на функции имеют тот же размер, что и указатели на объекты.

Вот краткий пример забавы с функциями-указателями-членами:

#include <stdio.h>

class A {};

class B {};

class VirtD: public virtual A, public virtual B {

public:

   virtual int Dfunc() { return 5; };

};

typedef int (VirtD::* Derived_mfp)();

int main()

{

   VirtD virtd;

   Derived_mfp mfp = &VirtD::Dfunc;

   printf( "sizeof( mfp) == %u\n", (unsigned int) sizeof( mfp));

}

Отображает: sizeof (mfp) == 12 на MSVC.

Ответ 5

Размер указателя имеет мало общего с архитектурой (32 бит, 64 бит). 32bit обычно ссылается на то, что размер регистра 32 бит. В результате максимально возможное количество адресов, которые вы можете использовать с помощью одного регистра, 2^32. Таким образом, это сводится к эффективности адресации слотов памяти с использованием регистра.

Ответ 6

С 32-разрядным указателем вы можете указать более широкий диапазон памяти, чем с 16-разрядными указателями. Когда 32-разрядные указатели были стандартизованы, 64-разрядные процессоры были не очень популярны (или даже существуют?). Поэтому указатель не сможет вписаться в регистр CPU, что является очень важным фактором для скорости.

Ответ 7

Чтобы ответить на ваш вопрос: сам С++ очень мало говорит о размере указателя и, конечно же, не о том, что он должен быть 32 бита или что-то еще. Размер указателя должен быть естественным для архитектуры машины.

Ответ 8

Почему не 16-бит? Поскольку, предполагая плоское 32-разрядное адресное пространство, вы не можете адресовать каждый байт. Вдали от него: вы можете адресовать только 2 16 уникальные местоположения с 16-разрядным указателем. Даже если ваши указатели указывают только на слова, а не байты, это все равно оставляет 1073676288 несовпадающих слов.

Предполагая плоское 32-разрядное адресное пространство, вы уже можете обращаться к каждому байту с 32-разрядным указателем. На данный момент 64-битные указатели просто теряют пространство, если вы не хотите добавлять дополнительную информацию к каждому указателю. Например, на 32-битной PowerPC дескриптор функции на самом деле является 96-битным сущностью, причем одна треть указывает на исполняемый код, а остальные - данные, которые облегчают перемещение модулей.

В сегментированном адресном пространстве могут быть полезны более крупные, чем 32-разрядные указатели на данные. Windows NT на DEC Alpha была 32-разрядной операционной системой, но оборудование Alpha было 64-битным. Ваше обычное адресное пространство все еще было 32-битным, но были специальные API-интерфейсы, позволяющие 32-разрядным программам обращаться к 64-разрядным адресам, как если бы они находились в недоступных для других сегментах.