Что делает "указатель на переменную регистра" как параметр функции?
Насколько я понимаю, register
Спецификатор подсказывает компилятору сохранить переменную в регистре. Это было все хорошо, пока я не наткнулся на следующую декларацию в XKBlib.h
из Xorg-7.7:
extern int XkbTranslateKeySym(
Display * /* dpy */,
register KeySym * /* sym_return */,
unsigned int /* modifiers */,
char * /* buffer */,
int /* nbytes */,
int * /* extra_rtrn */
);
Обратите внимание, как sym_return
передается как указатель на переменную регистра. Что заставляет меня задуматься о том, что
- это кажется допустимым, несмотря на невозможность получения адреса переменной регистра,
- это кажется каким-то важным для упоминания в объявлении функции.
Пункт 1. представляется неверным, потому что я могу передать указатель наregister
переменная, даже с -pedantic-errors
флаг для GCC.
Итак, что же меняет это объявление по сравнению с тем, в котором пропущено register
ключевое слово? Это меняет соглашение о вызовах или как?
2 ответа
register
Ключевое слово - это, в основном, устаревшая функция в современном C. Оно делает две вещи:
- Скажите компилятору, что он должен попытаться сохранить переменную в регистре процессора, если это возможно. Компилятор в настоящее время гораздо больше подходит для таких вызовов, чем программист, и поэтому является устаревшей функцией.
- Блокирует программиста от получения адреса переменной.
В вашем случае это говорит о том, что сам указатель, а не данные, на которые он указывает, предпочтительно должен быть сохранен в регистре, предположительно регистре адреса / индекса. От стандартного представления C это не делает ничего кроме этого.
Может случиться так, что определенный экзотический компилятор выбирает определенное соглашение о вызовах, когда register
как часть функции, хотя я никогда не видел этого раньше. Практика для соглашения о вызовах - это нечто вроде: "если параметр n является указателем, сохраните его в индексном регистре x, если параметр n+1 является указателем, сохраните его индексным регистром y" и тому подобное.
Я подозреваю, что наиболее вероятное объяснение register
Ключевым словом здесь является то, что программист не знал, что они делают. Тем более что в заголовке не было никаких комментариев по этому поводу - это довольно верный признак некомпетентности. Если посмотреть на заголовок в целом, есть много других признаков, поддерживающих теорию некомпетентности, таких как эта вопиющая ошибка: #define XkbLC_BeepOnComposeFail (1<<31)
, Если вы сможете найти UB в течение нескольких минут после краткого обзора источника, держитесь подальше от него.
Это не берет адрес регистровой переменной, то есть это не указатель на регистровую переменную. Скорее это намекает на то, что сам указатель (помните, указатели просто переменные) должен быть помещен в регистр.