Это исправление ошибки в старых версиях Visual C ++ (v6.0 и более ранних). В прошлом Visual C ++ нарушал правила области видимости для переменных, объявленных внутри операторов for
:
// This compiles in old versions of Visual C++, but it is in fact INVALID C++
for(int i = 0; ...)
{
...
}
for(i = 0; ...)
{
}
Другими словами, Visual C ++ предоставляет i
область видимости, как если бы она была объявлена вне цикла, и позволяет вам продолжать использовать ее после завершения цикла. Это приводит к коду, подобному приведенному выше фрагменту. В более совместимых со стандартами компиляторах i
больше не находится в области действия при определении второго цикла for
, поэтому компилятор выдает ошибку о том, что i
не определено.
Чтобы исправить это, некоторые люди использовали этот макрос (или очень похожие, эквивалентные макросы):
#define for if(0) {} else for
Это меняет цикл for
на следующее:
if(0)
{
}
else
for(int i = 0; ...)
{
...
}
Это помещает цикл for
в дополнительный уровень области видимости, так что любые переменные, объявленные в цикле for
, впоследствии будут вне области видимости, независимо от ошибки Visual C ++. Это гарантирует, что один и тот же код корректно компилируется корректно как в Visual C ++, так и в компиляторах, соответствующих стандартам, и что некорректный код не компилируется корректно.
Также обратите внимание, что если макрос был определен следующим образом:
// DO NOT USE
#define for if(1) for
Тогда, хотя это могло бы иметь тот же эффект для некоторого простого кода, это внезапно привело бы к неправильной компиляции следующего кода:
if(foo)
for(...)
{
...
}
else
doSomething();
Потому что, если вы развернете макрос, вы получите это:
if(foo)
if(1)
for(...)
{
...
}
else
doSomething();
И else
теперь совпадает с неправильным if
! Таким образом, разумное использование if(0) {} else
вместо if(1)
позволяет избежать этой проблемы.
Как последнее замечание, #define for if(0) {} else for
не вызывает бесконечной рекурсии, потому что препроцессор не будет рекурсивно заменять макрос, который вы в настоящее время определяете. Это сделает только одну замену в этом случае.