Стоит ли определять тривиальные встроенные методы дважды, основываясь на состоянии отладки / выпуска проекта? - PullRequest
0 голосов
/ 27 мая 2009

Я всегда задавался вопросом, хорошо это или плохо - тривиальный метод определять дважды, в зависимости
если проект находится в состоянии отладки / выпуска. Это для встраивания их. Например, Foo.h:


class Foo
{
        public:
                ...

                const bool& IsBoolean() const;

        private:
                bool _boolean;
};

#ifndef _DEBUG

/** We're in release, so let's advice compiler to inline this...
  *
  *
  */

inline const bool& Foo::IsBoolean() const
{
        return _boolean;
}

#endif

А теперь в Foo.cpp:


#include "Foo.h"

...

#ifdef _DEBUG

/** We're debugging this, no need for inlining...
  *
  *
  */

const bool& Foo::IsBoolean() const
{
        return _boolean;
}

#endif

Это совершенно бесполезно? Например, из-за способности компилятора (MSVC) самостоятельно встроить / оптимизировать методы?

Тем не менее, это то, что я использую в течение многих лет. Пожалуйста, поправьте меня, если я здесь совершенно не прав ...

Ответы [ 4 ]

9 голосов
/ 27 мая 2009

Это пустая трата времени по нескольким причинам.

Встроенное ключевое слово является подсказкой , которую компилятор может игнорировать по желанию. Точно так же, как это свободно встраивать, даже если ключевое слово не указано. Так что, добавите ли вы его или нет, вероятно, ничего не изменится для компилятора

Кроме того, любые функции, определенные внутри определения класса, неявно встроены. Вот почему короткие функции, такие как методы получения и установки, почти всегда определяются внутри определения класса.

Далее, если вы хотите пометить функцию как встроенную, нет причин не делать этого и в отладочных сборках.

Ключевое слово inline не имеет ничего общего с компилятором, фактически встроенным в функции. Это отдельные понятия. Функция, помеченная inline программистом, означает, что компоновщик не должен беспокоиться, если видит несколько идентичных определений. Обычно это происходит, если функция определена в заголовке, который включается в несколько модулей компиляции. Если функция помечена как встроенная, компоновщик объединит определения вместе. Если это не так, вы получите ошибку. Другими словами, добавление и удаление этого ключевого слова приведет к ошибкам компилятора. Это, вероятно, не то, что вы хотите.

Единственная причина, по которой существует некоторое совпадение между ключевым словом C ++ inline и оптимизацией компилятора, заключается в том, что если функция помечена inline, ее можно безопасно включить # в каждую единицу компиляции, что означает всегда будет виден при вызове функции. И это делает компилятором easire встроенными вызовами функции.

Наконец, встраивание не всегда повышает производительность. Легко создать ситуацию, когда встраивание ничего не делает, а только увеличивает размер кода, приводит к большему количеству пропусков кэша и в целом замедляет ваш код. Это одна из причин, по которой inline (в лучшем случае) рассматривается оптимизатором как подсказка. В худшем случае он полностью игнорируется.

То, что вы делаете, будет 1) вызывать ошибки компилятора в режиме отладки, которых не было в сборках релиза, и 2) не влиять на производительность.

2 голосов
/ 27 мая 2009

Похоже на пустую трату и ненужное дублирование кода. Обычно компилятор способен самостоятельно определять, какие функции встроены, а какие нет. Тем более, если вы используете MSVC с переключателем /LTCG (Link Time Code Generation), это означает, что ваши тривиальные методы будут встроены, даже если они в cpp.

1 голос
/ 27 мая 2009

Самое простое, что вы хотите сделать, это поместить код в собственный файл filename.inl , а затем условно включить файл либо в заголовок, либо в исходный файл. Вам также следует добавить префикс функций в файле .inl к условному макросу, который расширяется до inline , если файл включен в заголовок и в противном случае к пустому макросу.

1 голос
/ 27 мая 2009

Повторение плохое. Даже если вы имеете дело с мертвым компилятором, в худшем случае вы можете легко избежать этого повторения, используя макрос INLINE, определенный в одном месте или inline или ничего.

...