встроенный против constexpr? - PullRequest
       25

встроенный против constexpr?

28 голосов
/ 19 августа 2011

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

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

Ответы [ 3 ]

33 голосов
/ 19 августа 2011

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

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

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

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

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

3 голосов
/ 19 августа 2011

Цитировать Википедию:

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

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

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

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

0 голосов
/ 09 октября 2017

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

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

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

...