Адрес регистровой переменной

6 ответов

Вот отрывок из раздела 6.7.1 (сноска 101) стандарта C99 (pdf) :

Реализация может обрабатывать любой регистр просто как объявление auto . Однако, независимо от того, используется ли адресное хранилище на самом деле или нет, адрес любой части объекта, объявленного с помощью регистра спецификатора класса хранилища, не может быть вычислен , либо явно (с использованием унарных & ], как описано в 6.5.3.2) или неявно (путем преобразования имени массива в указатель, как описано в 6.3.2.1). Таким образом, единственный оператор, который может быть применен к массиву, объявленному со спецификатором класса хранения register , - это sizeof .

И из Раздела 7.1.1, Параграфа 3 ] Стандарт C ++ (pdf) :

Спецификатор регистра имеет ту же семантику, что и спецификатор auto , вместе с подсказкой реализации, что объявленный таким образом объект будет интенсивно использоваться. [Примечание: подсказку можно игнорировать, и в большинстве реализаций она будет проигнорирована, если будет взят адрес объекта. —В конце примечания]

Интересные факты о регистре

Группа C ++ (WG21) хочет отказаться от регистра :

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

Примечания с мартовского собрания 2009 г .:

Группа CWG согласилась с тем, чтобы исключить регистр .

Посмотрите, что группа C99 (WG14) сказала о регистре (pdf) на собрании:

Общее соглашение об исключении ключевого слова « auto ». Следует ли нам попросить WG21 вернуться к предыдущее использование « регистр » (без адреса)? Нет, это не сработает с WG21.

31
ответ дан 1 December 2019 в 00:33
поделиться

Ключевое слово register является только подсказкой и может быть проигнорировано. Большинство компиляторов C ++ игнорируют его все время, но любой компилятор C ++ проигнорирует его, если вы возьмете адрес переменной или создадите ссылку на нее.

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

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

Соответствующая часть стандарта C ++ - 7.1.1.3:

Спецификатор регистра имеет ту же семантику, что и автоматический спецификатор, вместе с подсказкой реализации, что объявленный таким образом объект будет активно использоваться. [Примечание: подсказку можно проигнорировать, и в большинстве реализаций она будет проигнорирована, если будет взят адрес объекта. —В конце примечания]

5
ответ дан 1 December 2019 в 00:33
поделиться

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

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

1
ответ дан 1 December 2019 в 00:33
поделиться

Важно помнить, что «регистр» - это всего лишь подсказка для компилятора (к тому же бессмысленная; я никогда не видел улучшения скорости, и, вероятно, большинство компиляторов просто игнорируйте это). И C, и C ++ могут игнорировать ваш «совет» и сохранять переменную в памяти. Конечно, если вы возьмете адрес переменной, он заставит ее назначить место в памяти.

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

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

1
ответ дан 1 December 2019 в 00:33
поделиться

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

0
ответ дан 1 December 2019 в 00:33
поделиться

C и C ++ - это два разных языка, с большое общее подмножество. Вот почему некоторые вещи между ними различаются.

Хотя я не понимаю вашего вопроса, регистр является (по крайней мере, в C ++) намеком на то, что к переменной можно обращаться чаще, и не более того. В языке C это означает, что вы не можете взять адрес с помощью унарного оператора и , что в то время имело определенный смысл. В первые дни C ожидалось, что компилятор может не беспокоиться о выделении памяти для переменной, и поэтому не обязательно будет адрес, который нужно взять.

(Компьютеры обычно имеют регистры, которые являются частями быстрого доступа CPU, и, следовательно, самое быстрое хранилище для доступа. Переменная могла бы находиться в регистре, а не в памяти, если бы это привело к повышению производительности.)

В настоящее время почти все компиляторы достаточно сложны, чтобы выполнять собственное распределение лучше, чем это может сделать программист, поэтому использование регистра ] почти всегда бессмысленна.

0
ответ дан 1 December 2019 в 00:33
поделиться