Если я определю следующее в программе C ++ 98:
#define BITS_PER_FOO 2
#define BITS_PER_BAR 3
#define FOOBARS (1<<(BITS_PER_FOO*BITS_PER_BAR))
тогда будет FOOBARS
быть оцененным как 64 прекомпилятором? Или же операция умножения и сдвига будет происходить в каждом месте, которое я использую FOOBARS
в коде?
Нет, так как это не дело препроцессора. Это делает обычную замену вещи, а не постоянное складывание.
Однако любой разумный компилятор будет выполнять постоянное свертывание, поэтому не следует ожидать, что это будет соответствовать инструкциям, выполняемым во время выполнения.
Прекомпилятор просто выполняет подстановку текста — это по сути копия & наклеить на стероиды. Это означает, что выражение, которое вы написали для FOOBAR
будет расширен в полном объеме в каждом месте замены.
Теперь любой порядочный компилятор все равно будет оценивать все это выражение во время компиляции. Тем не менее, вы можете сэкономить на этом некоторую работу (и иметь некоторые дополнительные преимущества, такие как четкий тип выражения, более четкая диагностика, меньше неожиданностей, возникающих из-за подстановок в неправильных местах, и фактическое значение l для ваших констант вместо выражений) путем определяя эти значения как фактические константы, например:
const int bits_per_foo = 2;
const int bits_per_bar = 3;
const int foobars = 1<<(bits_per_foo*bits_per_bar);
Операция умножения и сдвига битов будет выполняться в каждом месте, которое вы используете FOOBARS
,
Увидеть: Директива #define (C / C ++)
#define
образует макрос, означающий, что идентификатор заменяется на все в строке токена. В вашем случае препроцессор заменяет экземпляры FOOBARS
с выражением (1<<(BITS_PER_FOO*BITS_PER_BAR))