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

Встроенная функция против макрофункции

Возможный дубликат:
Встроенные функции против макросов препроцессора

Я хочу знать разницу между встроенной функцией и функцией макроса.

1) встроенная функция - это то же самое, что и функция макроса?

2) Я знаю, что оба они не вызываются, но на этапе компиляции они заменяются кодом. не?

3) Если есть разница, не могли бы вы указать его?

4b9b3361

Ответ 1

Inline заменяет вызов функции с телом функции, однако inline - это просто запрос к компилятору, который может быть проигнорирован (вы все равно можете передать некоторые флаги компилятору для принудительного ввода или использования атрибута always_inline с gcc).

Макрос, с другой стороны, расширяется препроцессором перед компиляцией, поэтому он точно так же, как и подстановка текста, также макросы не проверяются по типу, встроенные функции. Там есть сравнение в wiki.

Для полноты вы все равно можете иметь некоторую безопасность типов с помощью макросов, например, с помощью gcc __typeof__, следующие генерируют почти идентичный код и оба вызывают предупреждения при использовании с неправильными типами:

#define max(a,b) \
  ({ __typeof__ (a) _a = (a); \
      __typeof__ (b) _b = (b); \
    _a > _b ? _a : _b; })

__attribute__((always_inline)) int max(int a, int b) {
   return (a > b ? a : b);
}

Примечание: иногда нетривированные макросы - это то, что нужно, например, посмотреть, как uthash использует макросы для создания любой структуры C хешировать, не прибегая к кастам.

Ответ 2

1) Нет.

2) Макрос в C - это просто текст, который расширяется до того, как компилятор обработает исходный код. Ключевое слово inline используется как подсказка для компилятора о том, что функция может быть встроена в строку без необходимости создания стека вызовов.

Итак, например, скажем, что у вас есть следующие два фрагмента кода (сначала макрос, а затем встроенная функция):

#define MAX(x,y)     (x > y ? x : y)

и

inline int max(int x, int y) { return x > y ? x : y; }

Когда препроцессор находит в вашем коде следующий вызов:

int highest = MAX (var_1, var_2);

он заменяет его

int highest = (var_1 > var_2 ? var_1 : var_2);

Выше было то, что компилятор в конечном итоге получает во время процесса компиляции, поэтому фрагмент, определенный MAX (x, y), является заменой MAX (var_1, var_2). Когда компилятор находит вызов функции

int highest = MAX (var_1, var_2);

Затем вызывается функция "max". Вы должны предположить, что он называется обычным способом, потому что компилятор может игнорировать ваш "встроенный" намек и делать вызовы функции через обычный стек вызовов, а не просто размещать код для функции в том месте, где он находится встречаются.

Последнее предостережение с макросами: потому что это замена текста, а не замена кода, если вы выполните что-то вроде этого:

int highest = MAX (v1++, v2++);

препроцессор расширяет это значение до:

int highest = (v1++ > v2++ ? v1++ : v2++);

который, вероятно, не тот, который вы намеревались.

Ответ 3

Макросы - это декларации, которые заменяются препроцессором (до фактического компиляции). Это не функции вообще. Прежде чем начнется фаза компиляции, макросы давно исчезли, и все, что осталось, - это их расширения (включая расширение до нуля).

Встроенные функции - это, по сути, языковые функции, с правилами области видимости, объявлениями переменных, логическими конструкциями (петлями и т.д.) и т.д. Встроенная функция не разворачивается, как макросы. Они скомпилированы так же, как и обычный код, но могут быть затем введены (из-за отсутствия лучшего термина) в скомпилированный код и оптимизированы по мере необходимости.

Ответ 4

Нет inline не является таким же, как определение macro, поскольку макрос предварительно выполнен, но встроенный - это всего лишь указание на компилятор, чтобы поместить весь тело функции там, где он вызывается.

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

макроподстановка: preprocessing phase (т.е. перед компиляцией)

- файл ввода test.c в файле linux test.i

встроенная подстановка: compilation phase