Откуда ОС знает, на сколько нужно увеличивать разные указатели? - PullRequest
0 голосов
/ 01 июля 2011

В 32-битной ОС мы знаем, что размер указателя равен 4 байта, поэтому sizeof(char*) равен 4, sizeof(int*) равен 4 и т. Д. Мы также знаем, что при увеличении char* адрес байта (смещение) изменяется на sizeof(char); при увеличении int* адрес байта изменяется на sizeof(int).

Мой вопрос:

  • Откуда ОС знает, как увеличить байтовый адрес для sizeof(YourType)?

Ответы [ 5 ]

3 голосов
/ 01 июля 2011

Это в первую очередь проблема для компилятора C (или C ++), а не проблема для ОС как таковая.

Компилятор знает свои правила выравнивания для основных типов и применяет эти правила клюбой тип, который вы создаете.Поэтому он может установить требование и размер выравнивания YourType и будет гарантировать, что он увеличивает любую переменную YourType* на правильное значение.Правила выравнивания различаются в зависимости от аппаратного обеспечения (ЦП), и компилятор отвечает за знание того, какие правила применять.

Одним из ключевых моментов является то, что размер YourType должен быть таким, чтобы при наличии массива:1008 *

YourType array[20];

, затем &array[1] == &array[0] + 1.Адрес байта &array[1] должен быть увеличен на sizeof(YourType), и (при условии, что YourType является структурой), каждый из элементов array[1] должен быть правильно выровнен, так же, как элементы array[0] должны быть правильновыровнены.

3 голосов
/ 01 июля 2011

Компилятор знает, как увеличить указатель типа YourType *, только если он знает размер YourType, что имеет место в том и только в том случае, если полное определение YourType известно компилятору на этом этапе. .

Например, если у нас есть:

struct YourType *a;
struct YourOtherType *b;

struct YourType {
    int x;
    char y;
};

Тогда вам разрешено это сделать:

a++;

но вам не разрешено делать это:

b++;

.., поскольку struct YourType является завершенным типом, но struct YourOtherType является неполным типом.

Ошибка, заданная gcc для строки b++;:

error: arithmetic on pointer to an incomplete type
3 голосов
/ 01 июля 2011

ОС на самом деле не имеет к этому никакого отношения - это работа компилятора (как упомянуто @zneak).

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

0 голосов
/ 01 июля 2011

C указатели набираются, в отличие от некоторых старых языков, таких как PL / 1. Это не только позволяет узнать размер объекта, но и позволяет выполнять операции расширения и форматирования. Например, получение данных в * p, это float, double или char? Компилятор должен знать (например, разделение).

Конечно, у нас есть указатель без типа, void *, с которым вы не можете сделать никакой арифметики просто потому, что компилятор не знает, сколько добавить к адресу.

0 голосов
/ 01 июля 2011

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

Таким образом, 16-битной целевой программе на чипсете младшего класса может потребоваться определять типы иначе, чем в 32-битной системе.

Язык программирования и компилятор - это то, что управляет вашими типами.Не ОС или аппаратное обеспечение.

Хотя, конечно, попытка вставить 32-битное число в 16-битный регистр может быть проблемой!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...