Должен ли я использовать переменные класса регистров в современных программах на C?

В C ++ ключевое слово register было удалено в последнем стандарте ISO / IEC 14882: 2017 (C ++ 17).

Но и в C я часто вижу, что все больше и больше программистов склонны не использовать или не хотят объявлять объект с квалификатором класса register, потому что его целевое преимущество будет почти бесполезным, как в @user253751 ответ:

register не заставляет компилятор сохранять значение в регистре. register абсолютно ничего не делает. Только очень старые компиляторы использовали register, чтобы знать, какие переменные хранить в регистрах. Новые компиляторы делают это автоматически. Даже компиляторы 20-летней давности делают это автоматически.

  • Является ли использование register переменных класса и вместе с тем использование ключевого слова register устаревшим?

  • Должен ли я использовать register переменные класса в моих современных программах? Или это поведение излишне и устарело?


person RobertS supports Monica Cellio    schedule 07.01.2020    source источник
comment
Если он устарел, вы, вероятно, не захотите его использовать :)   -  person Michael Dorgan    schedule 07.01.2020
comment
@MichaelDorgan: в C ++ он устарел или удален, но я не думаю, что он есть в C.   -  person Fred Larson    schedule 07.01.2020


Ответы (4)


Нет никакой пользы от использования register. Современные компиляторы практически игнорируют это - они справляются с распределением регистров лучше, чем вы. Единственное, что он предотвращает, - это получение адреса переменной, что не является существенным преимуществом.

Ни один из моих собственных кодов больше не использует register. Код, над которым я работаю, теряет register, когда я приступаю к работе с файлом, но требуется время, чтобы просмотреть более 17000 файлов (и я меняю файл только тогда, когда у меня есть внешняя причина для его изменения, но это может быть неубедительной причиной. ).

person Jonathan Leffler    schedule 07.01.2020

Как заявил @JonathanLeffler, в большинстве случаев это игнорируется.

Некоторые компиляторы имеют специальный синтаксис расширения, если вы хотите сохранить переменную в определенном регистре.

gcc Глобальная или локальная переменная может быть помещена в конкретный регистр. Эта опция доступна не для всех платформ. Я знаю, что это реализовано в портах AVR и ARM.

пример:

register int x asm ("10");

int foo(int y)
{
    x = bar(x);
    x = bar1(x);
    return x*x;
}

https://godbolt.org/z/qwAZ8x

Дополнительная информация: https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/Explicit-Register-Variables.html#Explicit-Register-Variables

Но, честно говоря, я никогда не использовал его в своей жизни программирования (30 лет +)

person 0___________    schedule 07.01.2020

Он фактически устарел и не дает реальных преимуществ.

C - продукт начала 1970-х годов, и ключевое слово register служило намеком для компилятора, что а) этот конкретный объект будет использоваться много, поэтому б) вы можете захотеть сохранить его где-нибудь, кроме основной памяти - IOW , регистр или другую «быструю» память.

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

person John Bode    schedule 07.01.2020

Прежде всего, эта функция НЕ является устаревшей, потому что: «регистр» в этом контексте (глобальные или локальные регистровые переменные) является расширением GNU, которое не является устаревшим.

В вашем примере R10 (или регистр, который GCC внутренне назначает REGNO (reg) = 10) является глобальным регистром. «глобальный» здесь означает, что весь код в вашем приложении должен согласовывать такое использование. Обычно это не относится к коду из таких библиотек, как libc, libm или libgcc, потому что они не скомпилированы с -ffixed-10. Более того, глобальные регистры могут конфликтовать с ABI. Например, avr-gcc может передавать значения в R10. В avr-gcc, R2 ... R9 не используются ABI и не кодом из libgcc (за исключением 64-битного double).

В некоторых приложениях жесткого реального времени с avr-gcc я использовал глобальные регистры в (преждевременной) оптимизации, просто чтобы заметить, что прирост производительности был незначительным.

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

person emacs drives me nuts    schedule 08.01.2020