Определены ли в стандартах языка 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.