Определяют ли стандарты языка C поддержку переменных глобального регистра?

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


person user3282758    schedule 24.07.2015    source источник
comment
Вы также можете прочитать это   -  person StuartLC    schedule 24.07.2015


Ответы (5)


Существует распространенное заблуждение, что ключевое слово register языка C говорит об аппаратных регистрах. Это может быть источником этой концепции, но в современном C это не цель. Единственный реальный эффект, который имеет register, заключается в том, что & не допускается на таком звере.

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

И, чтобы ответить на ваш вопрос более прямо, register в области файлов не является частью языка C. Если бы это было так, это позволило бы нам объявить register const переменных практически любой базы, которые могли бы служить своего рода глобальные константы.

Сопоставление аппаратного регистра с конкретными переменными — это расширение, предоставляемое компиляторами, например, gcc. Функция Gcc, как расширение, также работает в области файлов. Но это довольно непомерно, поскольку обычно у ЦП не так много аппаратных регистров.

person Jens Gustedt    schedule 24.07.2015

register нельзя использовать для глобальных переменных. Это предусмотрено C11 6.9/2:

Ограничения

Спецификаторы класса хранения auto и register не должны появляться в спецификаторах объявления во внешнем объявлении.

Здесь внешнее объявление означает любое объявление, которое не находится внутри функции. (Не путать с extern или внешней связью).

person M.M    schedule 24.07.2015

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

Тем не менее,

  • #P3# <блочная цитата> #P4#
  • #P5# <блочная цитата> #P6#
person Sourav Ghosh    schedule 24.07.2015
comment
Интересно, почему Стандарт запрещал использование квалификатора регистра с глобальными переменными, поскольку такая вещь могла бы улучшить оптимизацию даже без выделения глобального регистра. Учитывая extern int foo; extern int *bar;, код foo++; *bar ^= 1; foo++; *bar ^= 2; должен выполнить все четыре шага по порядку. Если бы foo можно было уточнить по регистру, операции можно было бы переупорядочить как foo+=2; *bar^=3;. - person supercat; 28.01.2016

Переменные глобального регистра не поддерживаются или не разрешены C99 или C11. стандарты (см. Sourav Ghosh или ответы Мэтта Макнабба).

В качестве расширения GCC принимает

  register int *foo asm ("a5");

объявить глобальную переменную int, находящуюся в регистре a5... Это очень редко бывает полезно, и вам нужно понимать, как GCC генерирует код и выделяет регистры, каковы соглашения о вызовах вашего ABI, .. ... чтобы иметь возможность использовать это без опасений... Кстати, это, вероятно, ослабляет возможности оптимизации GCC.

Но если это специфично для GCC, Clang/LLVM делает не поддерживает это расширение, даже если оно поддерживает несколько других расширений GCC (например, вычисленные goto-s, ...).

person Basile Starynkevitch    schedule 24.07.2015
comment
На ARM, если программе требуется небольшое количество глобальных переменных, которые используются много, размещение всех таких переменных в структуре и выделение регистра для хранения их адреса избавит от необходимости загружать регистр индексирования при доступе к любой из этих переменных. Возможно, это не часто встречается в больших встроенных системах, но иногда очень полезно для небольших. - person supercat; 30.07.2015

Нет. В стандартах не указана такая функция. Класс хранения register ведет себя как auto и не может использоваться для глобальных переменных.

Как правило, все, что свойственно определенной машине, не является частью стандарта C.

person fuz    schedule 24.07.2015