(Встроенный) C: void function () или #define FUNCTION () - PullRequest
0 голосов
/ 21 июня 2010

Я программирую встроенные устройства, и мне было интересно, что использовать для макрофункции, например, инициализации некоторых регистров.я должен сделать это static / const или определить его как макрос?

, например, это:

 #define FPGA_INIT()\
{ \
  /* Set function and direction of start_code pin*/\
  P0SEL &= ~0x04; \
  P0DIR |= 0x04; \
  FPGA_START_CODE = 0; \
}

или это?в памяти-размещение?

Ответы [ 6 ]

6 голосов
/ 21 июня 2010

В целом, лучше всего зарезервировать использование макросов препроцессора для случаев, когда вам нужна способность препроцессора манипулировать кодом до его компиляции - вам не следует использовать макросы препроцессора для определения процедур, которые могут быть реализованыкак нормальные функции.Поскольку препроцессор заменяет код макроса везде, где вызывается макрос, может быть сложно отлаживать возникающие ошибки.Например, если вы вызываете свой макрос FPGA_INIT (), глобальные переменные (предположительно) P0SEL, P0DIR и FPGA_START_CODE могут быть скрыты местными жителями с тем же именем.

Если вы объявите функцию fpga_init (),Компилятор поместит код для этой функции вместе с кодом для других функций, которые вы объявляете, согласно тем правилам, которые он знает для платформы, на которую вы нацелены.Если вы объявите макрос FPGA_INIT (), компилятор никогда не узнает, что он существует, так как все ссылки на него будут разрешены препроцессором;компилятор будет видеть и компилировать операторы макроса отдельно в каждой вызванной им функции.

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

3 голосов
/ 21 июня 2010

Если вы используете макрос, то, где бы вы его ни использовали, препроцессор заменит его полным текстом.Это означает, что если вы скажете это скажем 10 раз, то вам потребуется в 10 раз больше памяти.Однако код будет выполняться быстрее, поскольку нет необходимости делать вызов функции.

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

1 голос
/ 21 июня 2010

Поместите функцию в заголовочный файл и введите префикс с ключевым словом inline:

inline void fpga_init()
{ 
  /* Set function and direction of start_code pin*/
  P0SEL &= ~0x04; 
  P0DIR |= 0x04; 
  FPGA_START_CODE = 0; 
}

Ключевое слово inline рекомендует компилятору размещать операторы «in-inline» вместе с другим кодом, аналогично#define макрос.Это лучше, чем макрос, потому что он ведет себя как функция и не имеет ошибок в макросе.

1 голос
/ 21 июня 2010

Макрос экономит ваши накладные расходы при вызове функции во время работы (скорость).

Функция избавляет вас от необходимости иметь один и тот же код в нескольких местах (пространство программы).

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

0 голосов
/ 03 февраля 2016

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

0 голосов
/ 21 июня 2010

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

...