Вот отрывок из раздела 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.
Ключевое слово register является только подсказкой и может быть проигнорировано. Большинство компиляторов C ++ игнорируют его все время, но любой компилятор C ++ проигнорирует его, если вы возьмете адрес переменной или создадите ссылку на нее.
С другой стороны, компилятор C ++ не имеет , чтобы игнорировать «регистр» только потому, что вы берете адрес переменной. Теоретически компилятор может сохранить его в регистре и дать вам какое-то значение волшебного указателя, которое каким-то образом отображается в регистр за кулисами, но это было бы много работы с очень небольшим выигрышем, поэтому компилятор (о котором я знаю) делает что-нибудь подобное.
Поскольку регистр игнорируется и в C, я подозреваю, что явный запрет на получение адресов регистровых переменных был просто для того, чтобы облегчить компиляторам C бремя проверки этого.
Соответствующая часть стандарта C ++ - 7.1.1.3:
Спецификатор регистра имеет ту же семантику, что и автоматический спецификатор, вместе с подсказкой реализации, что объявленный таким образом объект будет активно использоваться. [Примечание: подсказку можно проигнорировать, и в большинстве реализаций она будет проигнорирована, если будет взят адрес объекта. —В конце примечания]
Регистровая переменная не имеет адреса, она хранится (по крайней мере, должна храниться) в регистре процессора. Поскольку модификатор регистра - это не что иное, как подсказка, если вы заставите компилятор сгенерировать код для извлечения его адреса, модификатор будет проигнорирован, и вы получите обычную переменную, хранящуюся в памяти.
Чтобы напрямую ответить на ваш вопрос , в зависимости от того, какой из них позволяет вам использовать адрес регистровой переменной (ваш исходный пост противоречит сам себе ...), позволяет игнорировать вашу собственную подсказку и должно, по крайней мере, выдавать предупреждение. ИМО, правильная реализация запретила бы принимать адрес регистровой переменной.
Важно помнить, что «регистр» - это всего лишь подсказка для компилятора (к тому же бессмысленная; я никогда не видел улучшения скорости, и, вероятно, большинство компиляторов просто игнорируйте это). И C, и C ++ могут игнорировать ваш «совет» и сохранять переменную в памяти. Конечно, если вы возьмете адрес переменной, он заставит ее назначить место в памяти.
C и C ++ просто имеют разные правила о том, что вы можете делать, потому что это разные языки. Разработчики C ++ решили позволить вам получить адрес регистровой переменной, потому что это ничего не повредит; C не позволяет вам это делать, потому что он принудительно помещает их в память.
Если вдуматься, ограничение C, вероятно, связано с той же причиной, по которой переменные должны были быть объявлены в начале блока - компилятор может компоновку память для переменных по мере их обнаружения, независимо от того, как она используется позже в функции.
Это всего лишь обоснованное предположение, но я сомневаюсь, что вы можете взять адрес регистра в C ++, потому что такой мысли просто не существует. С ++, вероятно, не использует регистр в вашем конкретном случае. Обратите внимание, что квалификатор класса хранения регистр
является лишь подсказкой для компилятора (и большинство, если не все современные компиляторы с радостью полностью игнорируют его).
C и C ++ - это два разных языка, с большое общее подмножество. Вот почему некоторые вещи между ними различаются.
Хотя я не понимаю вашего вопроса, регистр
является (по крайней мере, в C ++) намеком на то, что к переменной можно обращаться чаще, и не более того. В языке C это означает, что вы не можете взять адрес с помощью унарного оператора и
, что в то время имело определенный смысл. В первые дни C ожидалось, что компилятор может не беспокоиться о выделении памяти для переменной, и поэтому не обязательно будет адрес, который нужно взять.
(Компьютеры обычно имеют регистры, которые являются частями быстрого доступа CPU, и, следовательно, самое быстрое хранилище для доступа. Переменная могла бы находиться в регистре, а не в памяти, если бы это привело к повышению производительности.)
В настоящее время почти все компиляторы достаточно сложны, чтобы выполнять собственное распределение лучше, чем это может сделать программист, поэтому использование регистра
] почти всегда бессмысленна.