Должен ли я использовать переменные класса регистров в современных C программах? - PullRequest
1 голос
/ 07 января 2020

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

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

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

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

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

Ответы [ 4 ]

5 голосов
/ 07 января 2020

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

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

3 голосов
/ 07 января 2020

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

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

g cc Глобальная или локальная переменная может быть помещена в конкретный регистр. Эта опция доступна не для всех платформ. Я знаю, что порты 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 лет +)

1 голос
/ 08 января 2020

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

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

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

Однако локальные переменные регистра очень удобны, когда дело доходит до интеграции не-ABI-функций, например, функций сборки, которые не соответствуют G CC ABI, без необходимости в обертках сборки.

1 голос
/ 07 января 2020

Это фактически устарело и не дает никакой реальной выгоды.

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

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

...