Я нахожусь в процессе обновления критичных к производительности библиотек для использования restrict, как это реализовано в C ++ 11 g ++ и MSVC с ключевым словом __restrict
, Это, кажется, самое стандартное расширение, поэтому я буду использовать restrict
а также __restrict
взаимозаменяемые.
restrict
является ключевым словом C99, но тем не менее компиляторы определили важные области его использования в C ++.
Этот пост намеревается быть «вопросом», спрашивающим о том, что такое каждое специфичное для C ++ использование и что это означает, за которым следует ответ CW, отвечающий на него. Не стесняйтесь добавлять / проверять / редактировать. Итак: «Помогите! Что эти C ++ использует из restrict
Ключевое слово значит?
квалификационный this
(ограничить метод):
void Foo::method(int*__restrict a) __restrict { /*...*/ }
Ограничить ссылку:
int&__restrict x = /*...*/;
Ограничить внутри шаблона:
std::vector<float*__restrict> x;
Ограничить член / поле. Технически это относится и к С struct
, но это возникает в C ++ чаще, чем в C:
class Foo final { public: int*__restrict field; };
квалификационный this
(ограничить метод):
Это означает, что this
указатель ограничен Это одно из главных следствий:
Метод не может работать на себя как данные, например:
void Foo::method(Foo*__restrict other) __restrict { /*...*/ }
В этом примере this
в противном случае псевдоним other
, restrict
говорит, что вы не можете вызвать этот метод с самим собой в качестве аргумента.
Примечание: это Хорошо чтобы получить доступ или изменить объект, даже через поле. Причина в том, что следующие функционально идентичны:
void Foo::method1(void) __restrict { field=6; }
void Foo::method2(void) __restrict { this->field=6; }
В этом примере this
не связан ни с чем.
Ограничить ссылку:
Похоже, это означает, что ссылка ограничена. Что это именно делает а полезно ли это другое дело. Кто-то на эта тема Компиляторы утверждений могут статически определять псевдонимы для ссылок, поэтому ключевое слово предположительно бесполезно. Этот вопрос Был также задан вопрос о том, следует ли его использовать, но ответ «конкретный поставщик» вряд ли поможет.
Прецедент на этот вопрос. Короче говоря, в функции f
, компилятор знает, что a.field
а также b.field
не псевдонимы:
class Foo final {
int*__restrict field;
};
int f(Foo a, Foo b) { /*...*/ }
Это часто будет иметь место, предполагая, a!=b
— Например, если поле выделено и уничтожено конструктором / деструктором Foo. Обратите внимание, что если поле является необработанным массивом, оно всегда будет истинным, и поэтому restrict
ключевое слово не нужно (и невозможно) применять.