Спецификатор класса хранения register
был создан при первом выпуске языка C , чтобы дать указание компилятору использовать один из регистров процессора для хранения переменной, имеющей область видимости, позволяющуюболее быстрый доступ.В то время написание кода требовало большого внимания со стороны программиста, потому что компиляторы не были настолько умны, чтобы обнаруживать ошибки или исправлять их, приводящие к ошибочному коду.понять некоторые детали.
Спецификатор класса хранения register
является одним из них.Итак, давайте начнем смотреть на спецификации, прежде чем комментировать их.
Из ИСО / МЭК 9899: 2011 , стандарт C11:
§6.7.1Спецификаторы класса хранения
Объявление идентификатора для объекта с регистром спецификатора класса хранения предполагает, что доступ к объекту должен быть максимально быстрым.Степень эффективности таких предложений определяется реализацией.(См. Примечание 119)
И примечание 119:
ПРИМЕЧАНИЕ
Реализация может обрабатывать любое объявление регистра просто какавто декларация.Однако независимо от того, используется ли адресное хранилище на самом деле, адрес любой части объекта, объявленной с помощью регистра спецификатора класса хранилища, не может быть вычислен ни явно, ни с помощью унарного оператора &
, как описано в 6.5.3.2), илинеявно (путем преобразования имени массива в указатель, как описано в 6.3.2.1).Таким образом, единственным оператором, который можно применить к массиву, объявленному с помощью регистра спецификатора класса хранения, является sizeof.
Это означает, что спецификатор хранения register
является предложением длякомпилятор использует регистры процессора или любые другие средства, чтобы сделать доступ к переменной максимально быстрым, но компилятор может принять другое решение.Он может обрабатывать объявленную переменную как стандартную переменную auto
.
В последнем случае технически возможно получить адрес хранилища, но это явно запрещено стандартом, как описано в примечании, нотакже применяется в ограничениях из §6.5.3.2 Операторы адреса и косвенности :
Операнд унарного оператора &
должен быть либо функциейуказатель, результат []
или унарного *
оператора или lvalue, который обозначает объект, который не является битовым полем и не объявляется с помощью register
спецификатора класса хранения .
Конечно, некоторые несовместимые компиляторы могут позволить вам применить оператор.
Теперь вернемся к самому вашему вопросу:
int *x = (int*) 0x1234;
X сейчас, похоже, не указывает на регистр, потому что такие адреса предназначены для памяти.Но я несколько раз пытался найти другой выглядящий адрес (также используя ключевое слово «register»).Даже в Интернете, кажется, никого не волнует.
Ваш пример неверен , вы объявляете указатель на int и присваиваете ему произвольный адрес,Это не имеет никакого отношения к спецификатору хранения register
.
Объявите register int *x = (int*) 0x1234;
, а затем попробуйте применить оператор &
к x
, как в int **pp = &x;
(обратите внимание, что мы объявляем указатель науказатель на int
, это то, что мы получаем, взяв адрес указателя на int
).
Вы получите ошибку на совместимых компиляторах.
Итак, мой главный вопрос: как выглядит адрес в указателе, когда он указывает на регистр?
Ответ прост: ничего не напоминает, потому что не может существовать в стандарте C .