Подтвердить что ты не робот

Inline против constexpr?

С новым стандартом С++ 11, когда следует использовать ключевое слово inline по ключевому слову constexpr? Является ли ключевое слово constexpr дополнительной оптимизацией по сравнению с inline или просто утверждает, что вещи должны вычисляться во время компиляции?

Почему constexpr работает в GCC в некоторых случаях, когда вызов не является постоянным, например вызов foo(x) в переменной constexpr? Является ли это ошибкой в ​​GCC или действительно ли она является частью стандарта?

4b9b3361

Ответ 1

Утверждение, что что-то может быть вычислено во время компиляции, - довольно сильная оптимизация.

Вложение просто удаляет вызов функции, копируя/вставляя тело функции в сайт вызова. Тело функции еще должно быть выполнено, вы просто сохраняете накладные расходы на вызов функции.

Но если вы будете оценивать один и тот же код во время компиляции, он свободен во время выполнения.

Но ни inline, ни constexpr в основном не связаны с оптимизацией. inline Основной целью является подавление правила с одним определением, так что функции могут быть определены в заголовках (что полезно для шаблонов и, кстати, также упрощает оптимизацию вложения)

И constexpr существует, потому что это полезно в метапрограммировании, и, кстати, это может помочь компилятору лучше оптимизировать код, перемещая больше вычислений во время компиляции.

Ответ 2

Процитировать wikipedia:

С++ 0x представит ключевое слово constexpr, которое позволяет пользователю гарантировать, что конструктор функции или объекта является временем компиляции константа.

Отметьте функции inline, если они супер короткие. Mark выполняет функции constexpr, если результаты требуются во время компиляции. (Параметры шаблона или размеры массива). Я считаю, что функция может быть как при необходимости.

Функция константного выражения или конструктор можно вызвать с помощью параметры неконференции. Подобно тому, как литерал constexpr integer может быть присвоенный переменной non-constexpr, так же может быть функция constexpr вызывать с параметрами неконференсперса, а результаты, хранящиеся в не-constexpr. Ключевое слово допускает только возможность постоянства времени компиляции, когда все члены выражения constexpr.

Итак, GCC не является неправильным в этом.

Ответ 3

Пока inline говорит компилятору: "Эта функция используется где-то в этой единицы перевода и не является общедоступной для других объектных файлов", вполне вероятно, что компилятор вставляет тело функции в вызывающий. constexpr функции говорят компилятору "Эта функция не имеет побочных эффектов и не зависит от предварительных условий, отличных от самого параметра".

constexpr переменные просто говорят: "Эта переменная не изменяется и ее данные могут быть включены в код". Однако имеет значение, если вы определяете переменную constexpr в функции статической или нестатической, например. если массив constexpr нестатический, gcc просто перемещает данные с жестко закодированными mov -Instructions в стек, а static constexpr просто сохраняет данные в разделе .text.

Лямбда-выражения без захвата, назначенные переменной, могут быть constexpr, кроме как с захватом, потому что без необходимости в них памяти не сохранять захват, и они работают как пустой класс с перегруженным operator() (но их даже можно отливать на простое функциональные указатели с простым унарным плюсом: +[]{}).