Макро против статических функций в заголовке

9

для многих быстрых задач, где можно использовать функцию f(x,y), в простом C используются макросы. Я хотел бы спросить конкретно об этих случаях, которые разрешаются вызовом функции (т. Е. Макросы, используемые для встраивания функций, а не для расширения кода произвольного кода).

Обычно функции C не являются встроенными, поскольку они могут быть связаны с другими файлами C. Однако статические функции C видны только из файла C, в котором они определены. Поэтому они могут быть встроены компиляторами. Я слышал, что многие макросы следует заменить, превратив их в статические функции, потому что это создает более безопасный код.

Есть ли случаи, когда это не очень хорошая идея?

Опять же: не спрашивать о макросах Code-Production с ## одинаковыми конструкциями, которые вообще не могут быть выражены как функция.

wirrbel
источник
4
Я думаю, что на ваш вопрос, возможно, ответили здесь stackoverflow.com/questions/9104568/macro-vs-function-in-c и здесь stackoverflow.com/questions/1358232/why-use-macros-in-c
Maru
Написание правильного макроса - это трудная задача, и если inlineфункции гарантируют, что он может быть определен несколько раз в двоичном файле, компилятор может решить, будет ли он фактически встроен в него, возможно, для экономии места
ratchet freak
2
Я на самом деле подозреваю, что большинство из них являются историческими причинами. Давным-давно компиляторы C вообще не встроили функции. Таким образом, люди использовали макросы для вещей, которые они хотели встроить. Код на C обычно необычайно долговечен.
Ян Худек
@ratchetfreak: C не имеет inline, это не о C ++.
wirrbel
2
@wirrbel Конечно, есть inlineв C, по крайней мере, с C99. Для быстрого обзора см. Википедию по встроенным функциям .
Амон

Ответы:

6

Макросы, которые можно решить с помощью вызова функции, имеют много подводных камней:

  • Их сложно написать, потому что вам, возможно, придется правильно обрабатывать такие аргументы, как ++i.
  • Их сложно отладить с помощью визуального отладчика, поскольку вы не можете пройти через макрос или поставить точку останова.
  • С ними трудно обращаться правильно при анализе зависимостей компиляции.

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

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

Нет причин, по которым компилятор не сможет предоставить две версии функции: традиционную called и inlined. Вы должны посмотреть на документацию компилятора, на который вы нацелены. Кроме того, вы можете захотеть взглянуть на сгенерированную сборку: даже если вы не знаете сборку, вы можете быстро научиться определять, была ли встроена какая-то функция или нет. (Начните с детских примеров, чтобы быстро выучить это.)

user40989
источник