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

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

5 ответов

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

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

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

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

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

Ограничения

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

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

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

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

  register int *foo asm ("a5");

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

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

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

Это сказало,

  • Глобальная переменная не может быть определена с register класс хранения, согласно C11Глава §6.9

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

  • Использование register не гарантирует распределение в реестре, глава §6.7.1 (выделено мной)

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

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

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

Другие вопросы по тегам