Как макросы обрабатываются препроцессором? - PullRequest
1 голос
/ 12 января 2012

Я читаю Efficient C ++ (более старая версия) и у меня есть некоторые сомнения.Вот, например, он говорит:

Когда вы делаете что-то подобное

#define ASPECT_RATIO 1.653

, символическое имя ASPECT_RATIO может никогда не быть замечено компиляторами;он может быть удален препроцессорами до того, как исходный код будет скомпилирован.В результате ASPECT_RATIO может никогда не войти в SYMBOLIC_TABLE.Это может сбить с толку, если вы получите ошибку во время компиляции с участием константы, потому что сообщение об ошибке может относиться к 1.653, а не к ASPECT_RATIO

. Я не понимаю этот параграф., Просто так.какие могут быть причины и насколько они осуществимы в реальном мире.

Спасибо

Ответы [ 3 ]

3 голосов
/ 12 января 2012

Это просто глобальный поиск и замена «ASPECT_RATIO» на «1.653» в файле перед передачей его компилятору

Вот почему макросы так опасны.Если у вас есть #define max 123 и переменная int max = 100, компилятор получит int 123 = 100, и вы получите ошибочное сообщение об ошибке

3 голосов
/ 12 января 2012

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

В основном, это описывает, как именно работает препроцессор C и C ++.Причина состоит в том, чтобы заменить макросы / константы (которые создаются с использованием директивы #define) их действительными значениями, вместо того, чтобы повторять одни и те же значения снова и снова.В C ++ это считается плохим стилем с использованием макросов в стиле C, но они поддерживаются для совместимости с C.

Препроцессор, как следует из названия, запускается до фактической компиляции и в основном меняет исходный кодкод в соответствии с указаниями препроцессора (начиная с #).Это также включает замену макросов их значениями, включение заголовочных файлов в соответствии с директивой #include и т. Д. И т. Д.

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

1 голос
/ 12 января 2012

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

По сути, «проблема», с которой вы столкнетесь при таком подходе, заключается в том, что ASPECT_RATIO не будетрассматривается компилятором как символ, то есть в отладчике и т. д. вы не можете запросить значение ASPECT_RATIO, как если бы оно было переменной.Это не значение, которое будет иметь адрес памяти, который может иметь static const int (я говорю «может», потому что оптимизирующий компилятор может решить действовать как препроцессор и оптимизировать необходимость явного адреса памяти длясохранить постоянное значение, вместо этого просто подставляя буквальное значение везде, где оно появляется в коде).В большем макросе функции он также не будет иметь адрес инструкции, как в реальной функции C / C ++, поэтому вы не можете устанавливать точки останова внутри макроса функции.Но в более общем смысле я не уверен, что назвал бы это «проблемой», если вы не намеревались использовать макрос в качестве символа отладки и / или не устанавливали точки прерывания отладки внутри вашего макроса.В противном случае макрос выполняет свою работу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...