Il s'agit de corriger un bogue dans les anciennes versions de Visual C++ (v6.0 et antérieures). Dans le passé, Visual C++ ne respectait pas les règles de portée concernant les variables déclarées à l'intérieur des fichiers for
déclarations :
// This compiles in old versions of Visual C++, but it is in fact INVALID C++
for(int i = 0; ...)
{
...
}
for(i = 0; ...)
{
}
En d'autres termes, Visual C++ donne i
une portée comme s'il était déclaré en dehors de la boucle, et il vous permet de continuer à l'utiliser après la fin de la boucle. Cela conduit à du code tel que le snippet ci-dessus. Dans les compilateurs plus conformes aux normes, i
n'est plus en vigueur lors de la définition de la seconde for
le compilateur émet donc une erreur à propos de i
étant indéfini.
Pour résoudre ce problème, certaines personnes ont utilisé cette macro (ou des macros équivalentes très similaires) :
#define for if(0) {} else for
Cela modifie le for
dans cette boucle :
if(0)
{
}
else
for(int i = 0; ...)
{
...
}
Cela met le for
à un niveau supplémentaire de portée, de sorte que toutes les variables déclarées dans la boucle for
sera hors de portée par la suite, quel que soit le bug de Visual C++. Cela permet de s'assurer que le même code compile correctement de manière cohérente à la fois dans Visual C++ et dans les compilateurs conformes aux normes, et que le code incorrect ne compile pas correctement de manière cohérente.
Notez également que si la macro était plutôt définie comme suit :
// DO NOT USE
#define for if(1) for
Alors que cela aurait le même effet pour un code simple, cela provoquerait soudainement une compilation incorrecte du code suivant :
if(foo)
for(...)
{
...
}
else
doSomething();
Parce que si vous développez la macro, vous obtenez ceci :
if(foo)
if(1)
for(...)
{
...
}
else
doSomething();
Et le else
correspond maintenant à la mauvaise if
! Ainsi, l'utilisation astucieuse de if(0) {} else
au lieu de if(1)
permet d'éviter ce problème.
En guise de conclusion, #define for if(0) {} else for
ne provoque pas de récursion infinie, car le préprocesseur ne remplacera pas récursivement la macro que vous êtes en train de définir. Il n'effectuera qu'un seul remplacement dans ce cas.