Я запутался в использовании register
ключевого слова в C. Обычно говорят, что его использование не нужно, как в этом вопросе о stackoverflow .
Является ли это ключевое слово полностью избыточным в C из-за современных компиляторов или есть ситуации, в которых оно все еще может быть полезным? Если да, то в каких ситуациях использование register
ключевого слова действительно полезно?
const
ключевом слове, но этот вопрос доказал, что я ошибался. Поэтому я подожду и посмотрю, что я получу.const
ключевое слово отличается от регистра.Ответы:
Это не избыточно с точки зрения языка, просто используя его, вы говорите компилятору, что вы «предпочли бы» иметь переменную, хранящуюся в регистре. Однако абсолютно нулевая гарантия того, что это действительно произойдет во время выполнения.
источник
Как уже упоминалось, оптимизаторы компилятора по сути делают
register
ключевое слово устаревшим для целей, отличных от предотвращения алиасинга. Тем не менее, существуют целые кодовые базы, которые скомпилированы с отключенной оптимизацией (-O0
на языке gcc ). Для такого кодаregister
ключевое слово может иметь большой эффект. В частности, переменные, которые иначе получили бы слот в стеке (то есть все параметры функции и автоматические переменные), могут быть помещены непосредственно в регистр, если объявлены сregister
ключевым словом.Вот реальный пример: предположим, что произошел некоторый поиск в базе данных и что код поиска вставил полученный кортеж в структуру C. Кроме того, предположим, что некоторое подмножество этой структуры C необходимо скопировать в другую структуру - возможно, эта вторая структура является записью в кэш, которая представляет метаданные, хранящиеся в базе данных, которые из-за ограничений памяти кэшируют только подмножество каждой записи метаданных, как хранимые в базе данных.
При наличии функции, которая получает указатель на каждый тип структуры и единственной задачей которого является копирование некоторых членов из исходной структуры во вторую структуру: переменные указателя структуры будут жить в стеке. Поскольку назначения происходят от членов одной структуры к другим, адреса структуры будут для каждого назначения загружаться в регистр для обеспечения доступа к членам структуры, которые копируются. Если указатели структуры должны были быть объявлены с
register
ключевым словом, адреса структур оставались бы в регистрах, эффективно вырезая инструкции загрузки адреса в регистр для каждого назначения.Опять же, помните, что приведенное выше описание относится к неоптимизированному коду.
источник
Вы в основном говорите компилятору, что не будете брать адрес переменной, и компилятор затем может якобы выполнять дальнейшую оптимизацию. Насколько я знаю, современные компиляторы довольно способны определить, может ли переменная / должна быть сохранена в регистре или нет.
Пример:
источник
В 16-битные компьютерные дни часто требовалось несколько регистров для выполнения 32-битных умножений и делений. Поскольку модули с плавающей запятой были встроены в микросхемы, а затем «взяли верх» 64-разрядные архитектуры, ширина регистров и их число расширились. В конечном итоге это приводит к полной реорганизации процессора. Смотрите Регистрация файлов в Википедии.
Короче говоря, вам понадобится немного времени, чтобы понять, что на самом деле происходит, если вы используете 64-битный чип X86 или ARM. Если вы используете 16-разрядный встроенный процессор, это может вам кое-что дать. Тем не менее, большинство небольших встроенных микросхем не запускают ничего критичного по времени - ваша микроволновая печь может отбирать данные у сенсорной панели 10 000 раз в секунду - ничего, что напрягает процессор с частотой 4 МГц.
источник
Чтобы определить, имеет ли ключевое слово register какое-либо значение, крошечные примеры кодов не подойдут. Вот c-код, который подсказывает мне, ключевое слово register по-прежнему имеет значение. Но с GCC в Linux все может быть иначе, я не знаю. Будет ли регистр int k & l храниться в регистре процессора или нет? Пользователи Linux (особенно) должны компилировать с GCC и оптимизацией. В Borland bcc32 ключевое слово register работает (в этом примере), так как & -operator выдает коды ошибок для объявленных в регистре целых чисел. НОТА! Это НЕ случай с крошечным примером с Borland на Windows! Чтобы действительно увидеть, что оптимизирует компилятор или нет, это должен быть более чем крошечный пример. Пустые петли не будут делать! Тем не менее, если адрес МОЖЕТ быть прочитан оператором &, переменная не сохраняется в регистре ЦП. Но если объявленная переменная регистра не может быть прочитана (вызывая код ошибки при компиляции) - я должен предположить, что ключевое слово register действительно помещает переменную в регистр CPU. Это может отличаться на разных платформах, я не знаю. (Если это сработает, количество «тиков» будет намного меньше при объявлении регистра.
источник