const fn против встроенного атрибута - PullRequest
0 голосов
/ 22 марта 2020

В следующем примере я считаю, что при вызове функции Struct::new ее тело будет встроено (скопировано) на сайт вызова из-за атрибута #[inline]. Это приведет к увеличению объема генерируемого кода и уменьшению времени компиляции, но улучшит производительность во время выполнения из-за исключенного вызова функции.

impl Struct {
    #[inline]
    pub fn new() -> Self {
        // initialization code
    }
} 

В настоящее время const fn стабильны в Rust. Когда кто-то объявляет функцию как const, он должен позволить компилятору оценить ее во время компиляции.

impl Struct {
    pub const fn new() -> Self {
        // initialization code
    }
} 

Означает ли объявление функции как const и пропуск атрибута #[inline] те же компромиссы, что и код в предыдущем примере (поскольку функция оценивается во время компиляции и ее результат "встроен" в колл-сайт)? Должны ли мы заменить все атрибуты #[inline] на const? Если они не одинаковы, в чем различия?

1 Ответ

5 голосов
/ 22 марта 2020

#[inline] и const - это совершенно разные вещи, и одно не является надмножеством другого:

  • #[inline] направляет компилятор, чтобы не сделать heuristi c решение о том, следует ли встроить тело функции в вызывающую функцию. Компилятор по-прежнему может полностью игнорировать этот атрибут или указывать c call-сайтов, если он выберет его по какой-либо причине, так как встраивание не изменяет поведение программы каким-либо видимым образом.
  • const является частью сигнатуры функции и гарантирует , что функция может быть (но не обязательно - ), оцененной во время компиляции. Компилятор может по своему усмотрению оценивать тело функции во время компиляции, но он может свободно перенести это во время выполнения. Причина создания функции const заключается в том, что возможность оценки в const-контексте является частью сигнатуры функции, гарантирующей это свойство в полустабильном виде. То есть функция, которая может быть вызвана в const-контексте, не должна внезапно терять это свойство без всплытия.

Выше приведена причина, по которой const является частью публично документированной подпись функции, но #[inline] - нет.

Так что нет, не меняйте вслепую #[inline] на const.

...