Зачем использовать явно бессмысленные операторы do-while и if-else в макросах?
Макросы — это копируемые/вставляемые c++ фрагменты текста, которые c++ препроцессор вставляет в c++-faq подлинный код; автор макроса c++ надеется, что замена даст c++-faq корректный код.
Есть три хороших c++-faq «совета», чтобы преуспеть c++-faq в этом:
Помогите макросу вести себя как настоящий код
Обычный код обычно cpp заканчивается точкой с запятой. Если cpp код просмотра пользователя cxx не нужен...
doSomething(1) ;
DO_SOMETHING_ELSE(2) // <== Hey? What's this?
doSomethingElseAgain(3) ;
Это означает, что cpp пользователь ожидает, что c-preprocessor компилятор выдаст ошибку, если c++-faq точка с запятой отсутствует.
Но cpp на самом деле действительно c++-faq хорошая причина заключается c-preprocessor в том, что в какой-то момент c++ автору макроса, возможно, потребуется c-preprocessor заменить макрос подлинной cxx функцией (возможно, встроенной). Так cpp что макрос должен действительно вести c++ себя как один.
Итак, у нас c++ должен быть макрос, которому c++-faq нужна точка с запятой.
Создайте действительный код
Как c++ показано в ответе jfm3, иногда c++ макрос содержит более одной cxx инструкции. И если макрос c++ используется внутри оператора cxx if, это будет проблематично:
if(bIsOk)
MY_MACRO(42) ;
Этот c макрос можно расширить следующим c++ образом:
#define MY_MACRO(x) f(x) ; g(x)
if(bIsOk)
f(42) ; g(42) ; // was MY_MACRO(42) ;
Функция g
будет выполняться c++ независимо от значения bIsOk
.
Это c-preprocessor означает, что мы должны добавить c область макроса:
#define MY_MACRO(x) { f(x) ; g(x) ; }
if(bIsOk)
{ f(42) ; g(42) ; } ; // was MY_MACRO(42) ;
Создать действительный код 2
Если макрос c-preprocessor примерно такой:
#define MY_MACRO(x) int i = x + 1 ; f(i) ;
У нас может c-preprocessor быть другая проблема в следующем cxx коде:
void doSomething()
{
int i = 25 ;
MY_MACRO(32) ;
}
Потому что это расширится c как:
void doSomething()
{
int i = 25 ;
int i = 32 + 1 ; f(i) ; ; // was MY_MACRO(32) ;
}
Этот код, конечно же, не c++ скомпилируется. Итак, опять cxx же, решение использует область c++ видимости:
#define MY_MACRO(x) { int i = x + 1 ; f(i) ; }
void doSomething()
{
int i = 25 ;
{ int i = 32 + 1 ; f(i) ; } ; // was MY_MACRO(32) ;
}
Код снова работает cpp корректно.
Комбинировать эффекты точки с запятой и области видимости?
Есть одна идиома c++-faq C/C++, которая производит c++-faq этот эффект: Цикл do/while:
do
{
// code
}
while(false) ;
do/while cxx может создать область действия, таким c образом инкапсулируя код c++-faq макроса, и нуждается в точке c с запятой в конце, таким cxx образом расширяясь в код, нуждающийся c-preprocessor в ней.
Бонус?
Компилятор C++ оптимизирует cxx цикл do/while, поскольку cxx тот факт, что его постусловие c++-faq ложно, становится известен c++-faq во время компиляции. Это cpp означает, что макрос вида:
#define MY_MACRO(x) \
do \
{ \
const int i = x + 1 ; \
f(i) ; g(i) ; \
} \
while(false)
void doSomething(bool bIsOk)
{
int i = 25 ;
if(bIsOk)
MY_MACRO(42) ;
// Etc.
}
будет c правильно расширяться как
void doSomething(bool bIsOk)
{
int i = 25 ;
if(bIsOk)
do
{
const int i = 42 + 1 ; // was MY_MACRO(42) ;
f(i) ; g(i) ;
}
while(false) ;
// Etc.
}
, а c++-faq затем компилируется и оптимизируется c++ как
void doSomething(bool bIsOk)
{
int i = 25 ;
if(bIsOk)
{
f(43) ; g(43) ;
}
// Etc.
}
c++
c
c-preprocessor
c++-faq
Зачем использовать явно бессмысленные операторы do-while и if-else в макросах?
Мы используем файлы cookies для улучшения работы сайта. Оставаясь на нашем сайте, вы соглашаетесь с условиями использования файлов cookies. Чтобы ознакомиться с нашими Положениями о конфиденциальности и об использовании файлов cookie, нажмите здесь.