Если я хочу использовать инструкции препроцессора #define
для упрощения определения и вычисления констант и общих функций и воспользоваться меньшим объемом ОЗУ (в отличие от использования значений const
). Однако я не уверен, как они решаются, если многие макросы используются вместе.Как скопированы макрокоманды в C?
Я разрабатываю свою собственную обработку DateTime
, похожую на временные метки linux, но для игры с обновлениями галочек, которые представляют собой 1/60 секунды. Я бы предпочел объявить ценности прикованными, но задаться вопросом, будет ли жестко закодированное значение работать быстрее.
#include <stdint.h>
// my time type, measured in 1/60 of a second.
typedef int64_t DateTime;
// radix for pulling out display values
#define TICKS_PER_SEC 60L
#define SEC_PER_MIN 60L
#define MIN_PER_HR 60L
#define HRS_PER_DAY 24L
#define DAYS_PER_WEEK 7L
#define WEEKS_PER_YEAR 52L
// defined using previous definitions (I like his style, write once!)
#define TICKS_PER_MIN TICKS_PER_SEC * SEC_PER_MIN
#define TICKS_PER_HR TICKS_PER_SEC * SEC_PER_MIN * MIN_PER_HR
#define TICKS_PER_DAY TICKS_PER_SEC * SEC_PER_MIN * MIN_PER_HR * HRS_PER_DAY
// ... so on, up to years
//hard coded conversion factors.
#define TICKS_PER_MIN_H 3600L // 60 seconds = 60^2 ticks
#define TICKS_PER_HR_H 216000L // 60 minutes = 60^3 ticks
#define TICKS_PER_DAY_H 5184000L // 24 hours = 60^3 * 24 ticks
// an example macro to get the number of the day of the week
#define sec(t)((t/TICKS_PER_DAY) % DAYS_PER_WEEK)
Если я использую sec(t)
макрос, который использует TICKS_PER_DAY
, который определяется 3 предыдущих макросов TICKS_PER_SEC * SEC_PER_MIN * MIN_PER_HR * HRS_PER_DAY
, делает это место повсюду в своем коде, который вызывает sec(t)
:
(t/5184000L) % 7L)
или же она расшириться каждый время до:
(t/(60L * 60L * 60L * 24L)) % 7L)
, так что на каждом этапе выполняются инструкции по дополнительному умножению ? Является ли это компромиссом между макросами и константными переменными, или я неправильно понимаю, как работает препроцессор?
UPDATE:
За многими полезными ответы, лучший дизайн для построения цепочки макросов, которые расширяют в постоянные выражения, чтобы обернуть определение в скобках для
1. Правильного порядка операций:
(t/60 * 60 * 60 * 24) != (t/(60 * 60 * 60 * 24))
2. поощрять постоянный Фелди~d нг компилятора путем группирования вместе постоянных значений:
// note parentheses to prevent out-of-order operations
#define TICKS_PER_MIN (TICKS_PER_SEC * SEC_PER_MIN)
#define TICKS_PER_HR (TICKS_PER_SEC * SEC_PER_MIN * MIN_PER_HR)
#define TICKS_PER_DAY (TICKS_PER_SEC * SEC_PER_MIN * MIN_PER_HR * HRS_PER_DAY)
Препроцессор не будет оптимизировать это, но любой компилятор, достойный его соли, сбросит его в одно постоянное значение. –
Итак, если я использую один такой, как gcc, я должен ожидать, что он будет рассматриваться как одно значение? Есть ли способ проверить, что он делает? – AaronCarson
Эти значения не являются * вложенными *; они являются * цепочками * расширений: расширения, которые используют макросы, расширения которых используют больше макросов. Вложенный, если он существует, означает, что тело макроса может определять макрос. – Kaz