Препроцессор, который обрабатывает такие вещи, как #define
, работает концептуально до анализа остальной части вашей программы. Среди прочего, это означает, что определения препроцессора не учитывают область видимости блока. Компилятор не замечает, если вы сделали #define
внутри блока {
... }
. Не существует механизма автоматического выполнения #undef
в конце блока {
... }
.
Вы можете сделать это вручную, если хотите: вы можете использовать #define
внутри блока и не забывать делать свои собственные, явные #undef
в конце блока. Но это все на вас: компилятор не проверит вашу работу или не предупредит вас, если вы ошиблись.
И по этой причине это считается плохой практикой. (Я думаю, это то, что вы подразумеваете под «запахом кода».) Это плохая практика, потому что она подвержена ошибкам, и нет хорошего автоматического способа отловить любые ошибки.
Если вы вообще используете препроцессор #define
, он должен быть глобальным (потому что, по сути, является глобальным, хотите вы того или нет).
И, конечно же, глобальные переменные тоже не одобряются. И это связано с тем, что в наши дни препроцессор #define
в значительной степени недоволен, все они.
Как и все вопросы стиля, этот может быть несколько спорным. Когда я говорю, что созданные вручную препроцессорные определения блоков являются «плохим стилем», это не значит, что против них существует железное правило. Если вы хотите, и вы знаете, что делаете, вы можете сойти с рук; никто здесь не может остановить тебя. (Если вы пишете код на работе и, в зависимости от руководства по стилю вашей компании, вы можете получить отчитывание в обзоре кода.)
Как оказалось, кодовая база, с которой я работаю каждый день на работе, полна этих определений препроцессора "локальной области видимости", потому что некоторые из моих предшественников думали, что они изящны, я полагаю. Они мне не нравятся, но они работают и не вызывают проблем, поэтому мы не начали кампанию по их искоренению.