Как встроенная функция отличается от макроса препроцессора?Встроенные функции против макросов препроцессора
ответ
Макросы препроцессора - это просто шаблоны замещения, применяемые к вашему коду. Их можно использовать практически в любом месте вашего кода, потому что они заменяются их расширениями перед началом компиляции.
Внутренние функции - это фактические функции, чье тело непосредственно впрыскивается в их сайт вызова. Они могут использоваться только там, где подходит вызов функции.
Теперь, насколько использование макросов vs. встроенных функций в функции, как контекст, иметь в виду, что:
- Макросы не типобезопасен, и может быть расширен, независимо от того, являются ли они синтаксически правильно - на этапе компиляции будут сообщаться ошибки, возникающие из-за проблем с макрообъемностью.
- Макросы могут использоваться в контексте, где вы не ожидаете, в результате чего возникают проблемы
- Макросы более гибкие, поскольку они могут расширять другие макросы, тогда как встроенные функции необязательно делают это.
- Макросы могут вызывать побочные эффекты из-за их расширения, поскольку входные выражения копируются везде, где они отображаются в шаблоне.
- Не всегда встроенная функция Inline - некоторые компиляторы делают это только в сборках релизов или когда они специально настроены для этого. Кроме того, в некоторых случаях встраивание может быть невозможно.
- Встроенные функции могут предоставить область переменных (в частности, статические), макросы препроцессора могут делать это только в блоках кода {...}, а статические переменные не будут вести себя точно так же.
Не всегда гарантируется встроенная функция: поскольку компилятор не будет встроен, если это приведет к созданию более медленного кода и т. Д. Компилятор делает много анализа, который Инженер не может и делает правильно. –
Я считаю, что рекурсивные функции - еще один пример, когда большинство компиляторов игнорируют inlining. – LBushkin
Существуют ли какие-либо важные различия в C по сравнению с C++ в этом случае? – rzetterberg
Ключевым отличием является проверка типа. Компилятор проверяет, передается ли то, что вы передаете в качестве входных значений, типов, которые могут быть переданы в функцию. Это неверно для макросов препроцессора - они расширяются до проверки любого типа и могут вызывать серьезные и труднообнаруженные ошибки.
Here - несколько других менее очевидных точек, обозначенных.
Встроенная функция ведет себя синтаксически, как обычная функция, обеспечивая безопасность типов и область действия для локальных переменных функций и доступ к членам класса, если это метод. Также при вызове встроенных методов вы должны придерживаться частных/защищенных ограничений.
Встроенная функция будет поддерживать семантику значений, тогда как макрос препроцессора просто копирует синтаксис. Вы можете получить очень тонкие ошибки с помощью макроса препроцессора, если вы используете этот аргумент несколько раз - например, если аргумент содержит мутацию типа «i ++», которая имеет два раза, это довольно неожиданно. Эта встроенная функция не будет иметь этой проблемы.
Макросы игнорируют пространства имен. И это делает их злыми.
Во-первых, макросы препроцессора - это всего лишь «скопировать пасту» в код перед компиляцией.Так что нет типа проверки, и некоторые побочных эффектов могут появиться
Например, если вы хотите сравнить 2 значения:
#define max(a,b) ((a<b)?b:a)
сторона появляются эффекты, если вы используете max(a++,b++)
, например (a
или b
будет увеличиваться дважды). Вместо этого следует использовать (например)
inline int max(int a, int b) { return ((a<b)?b:a); }
Просто добавьте к вашему примеру, что помимо побочного эффекта макрос может также ввести дополнительную рабочую нагрузку, рассмотрим 'max (fibonacci (100), factorial (10000))', более крупный будет вычисляться дважды :( – watashiSHUN
В GCC (я не уверен, о других), объявив функцию инлайн, это всего лишь намек на компилятор. В конце дня все еще зависит от компилятора, чтобы решить, включает ли он тело функции всякий раз, когда он вызывается.
Разница между встроенными функциями и макросами препроцессора относительно велика. Макросы препроцессора - это просто замена текста в конце дня. Вы отказываетесь от способности компилятора выполнять проверку проверки типов на аргументы и тип возвращаемого значения. Оценка аргументов сильно отличается (если выражения, которые вы передаете в функции, имеют побочные эффекты, вы будете очень весело отлаживать время). Существуют тонкие различия в том, где можно использовать функции и макросы. Например, если у меня было:
#define MACRO_FUNC(X) ...
Где MACRO_FUNC, очевидно, определяет тело функции. Особое внимание должно быть принято, так что работает правильно во всех случаях функция может быть использована, например, плохо написана MACRO_FUNC вызовет ошибку в
if(MACRO_FUNC(y)) {
...body
}
нормальная функция может быть использована без проблем там.
Чтобы добавить еще одно отличие от уже предоставленных: вы не можете пройти через #define
в отладчике, но вы можете выполнить встроенную функцию.
С точки зрения кодирования встроенная функция подобна функции. Таким образом, различия между встроенной функцией и макросом совпадают с различиями между функцией и макросом.
С точки зрения компиляции встроенная функция похожа на макрос. Он вводится непосредственно в код, не вызываемый.
В целом, вы должны учитывать, что встроенные функции являются регулярными функциями с некоторой незначительной оптимизацией, смешанной. И, как и большинство оптимизаций, до компилятора решать, действительно ли это необходимо применить. Часто компилятор с радостью игнорирует любые попытки программиста встроить функцию по различным причинам.
встроенные функции аналогичны макросам (поскольку код функции расширяется в точке вызова во время компиляции), встроенные функции анализируются компилятором, тогда как макросы расширяются препроцессором. В результате существует несколько важных отличий:
- Встроенные функции соответствуют всем протоколам типа безопасности, действующим на нормальных функциях.
- Встроенные функции задаются с использованием того же синтаксиса, что и любая другая функция, за исключением того, что они включают ключевое слово inline в объявлении функции.
- Выражения, переданные как аргументы встроенным функциям, оцениваются один раз.
В некоторых случаях выражения, переданные в качестве аргументов для макросов, могут быть оценены более одного раза. http://msdn.microsoft.com/en-us/library/bf6bf4cf.aspx
макросы расширяются за время предварительной компиляции, вы не можете использовать их для отладки, но вы можете использовать встроенные функции.
-- good article: http://www.codeguru.com/forum/showpost.php?p=1093923&postcount=1
;
Спасибо, сэр за ваш ответ. – Subodh
встроенные функции будут вести себя как вызов функции, если в нем есть итеративный или рекурсивный оператор, чтобы предотвратить повторное выполнение инструкций. Это очень полезно для сохранения общей памяти вашей программы.
функцияинлайн расширяется компилятором, где, как макросы развернутом препроцессора, который просто текстуальное substitution.Hence
Там нет проверки типа во время вызова макроса во время проверки типа делаются во время вызов функции.
Нежелательные результаты и неэффективность могут возникать во время расширения макросов из-за переоценки аргументов и порядка операций. Например
#define MAX(a,b) ((a)>(b) ? (a) : (b)) int i = 5, j = MAX(i++, 0);
приведет
int i = 5, j = ((i++)>(0) ? (i++) : (0));
макросоци- аргументы не оценены до макроподстановкам
#define MUL(a, b) a*b int main() { // The macro is expended as 2 + 3 * 3 + 5, not as 5*8 printf("%d", MUL(2+3, 3+5)); return 0; } // Output: 16`
Возвращение ключевого слова не могут быть использованы в макросах возвращать значения, как в случай функций.
Встраиваемые функции могут быть перегружены
Маркеры, передаваемые макросы могут быть объединены при помощи оператора ##, называемый оператором Токен-наклеивая.
Макросы обычно используются для повторного использования кода, когда встроенные функции используются для устранения временных затрат (избыточного времени) во время вызова функции (избегая перехода к подпрограмме).
- 1. C++ функции constexpr для тестирования макросов препроцессора
- 2. Подсчет макросов препроцессора
- 3. Возможно использование макросов препроцессора?
- 4. Фиджи не распознает встроенные функции макросов
- 5. Встроенные функции против библиотечных функций
- 6. Неизвестного типа C препроцессора макросов
- 7. Сочетание макросов и переменных препроцессора
- 8. Можно ли использовать функцию препроцессора для определения нескольких макросов препроцессора?
- 9. Использование встроенных макросов препроцессора в Swift
- 10. Внешние определения макросов препроцессора в GLSL
- 11. Встроенные функции/методы против собственных функций/методов?
- 12. многоуровневая отладка с использованием макросов препроцессора c
- 13. Использование инструкций препроцессора для макросов в C
- 14. Сформировать список макросов препроцессора, определенных компилятором
- 15. Действительные токены препроцессора в конкатенации макросов
- 16. Как определить платформу/компилятор из макросов препроцессора?
- 17. Xcode 7: установка макросов препроцессора для архитектуры
- 18. Xcode 6: Набор макросов препроцессора в архитектуре
- 19. препроцессора макросы в качестве параметров других макросов
- 20. Определение макросов препроцессора C++ со SCons
- 21. C++ Постоянных макросов препроцессора и шаблоны
- 22. C++/VS2008: Выполнение макросов против функций Инлайн
- 23. Использовать выходные данные препроцессора как встроенные сборки
- 24. Встроенные системы: Сокеты против MSMQ
- 25. Есть ли возможность определения макросов препроцессора #define в VB.NET?
- 26. встроенные функции
- 27. Встроенные функции
- 28. Реализация встроенные функции в заголовочных файлах против .cpp файлов
- 29. Встроенные функции и конструктор копирования
- 30. Определение макросов функции
Я отметил это как домашнюю работу, хотя это может быть законный вопрос. Пока все ваши вопросы задаются домашними вопросами, и один из них закрыт как таковой. –
Ответы на http://stackoverflow.com/questions/132738/why-should-i-ever-use-inline-code содержит некоторую информацию, связанную с вашим вопросом. –