Comme on l’a noté, il existe deux écoles de pensée à ce sujet.
1) Déclarez tout en haut des fonctions car l'année est 1987.
2) Déclarez le plus proche de la première utilisation et dans la plus petite portée possible.
Ma réponse à cela est FAITES LES DEUX! Laisse-moi expliquer:
Pour les fonctions longues, 1) rend la refactorisation très difficile. Si vous travaillez dans une base de code où les développeurs sont contre l'idée de sous-routines, alors vous aurez 50 déclarations de variables au début de la fonction et certaines d'entre elles pourraient simplement être un "i" pour une boucle for qui est au plus bas de la fonction.
J'ai donc développé la déclaration au sommet du SSPT à partir de cela et j'ai essayé de faire l'option 2) religieusement.
Je suis revenu à la première option à cause d'une chose: des fonctions courtes. Si vos fonctions sont assez courtes, alors vous aurez peu de variables locales et comme la fonction est courte, si vous les mettez en haut de la fonction, elles seront toujours proches de la première utilisation.
De plus, l'anti-modèle de «déclarer et définir à NULL» lorsque vous voulez déclarer en haut mais que vous n'avez pas fait certains calculs nécessaires à l'initialisation est résolu car les choses que vous devez initialiser seront probablement reçues comme arguments.
Alors maintenant, je pense que vous devez déclarer en haut des fonctions et aussi près que possible de la première utilisation. Alors les deux! Et la façon de le faire est d'utiliser des sous-programmes bien divisés.
Mais si vous travaillez sur une fonction longue, mettez les choses les plus proches de la première utilisation, car de cette façon, il sera plus facile d'extraire des méthodes.
Ma recette est la suivante. Pour toutes les variables locales, prenez la variable et déplacez sa déclaration vers le bas, compilez, puis déplacez la déclaration juste avant l'erreur de compilation. C'est la première utilisation. Faites ceci pour toutes les variables locales.
int foo = 0;
<code that uses foo>
int bar = 1;
<code that uses bar>
<code that uses foo>
Maintenant, définissez un bloc de portée qui commence avant la déclaration et déplacez la fin jusqu'à ce que le programme se compile
{
int foo = 0;
<code that uses foo>
}
int bar = 1;
<code that uses bar>
>>> First compilation error here
<code that uses foo>
Cela ne compile pas car il y a plus de code qui utilise foo. Nous pouvons remarquer que le compilateur a pu parcourir le code qui utilise bar car il n'utilise pas foo. À ce stade, il y a deux choix. La mécanique consiste simplement à déplacer le "}" vers le bas jusqu'à ce qu'il se compile, et l'autre choix est d'inspecter le code et de déterminer si l'ordre peut être changé en:
{
int foo = 0;
<code that uses foo>
}
<code that uses foo>
int bar = 1;
<code that uses bar>
Si l'ordre peut être changé, c'est probablement ce que vous voulez, car cela raccourcit la durée de vie des valeurs temporaires.
Une autre chose à noter, est-ce que la valeur de foo doit être préservée entre les blocs de code qui l'utilisent, ou pourrait-il simplement être un foo différent dans les deux. Par exemple
int i;
for(i = 0; i < 8; ++i){
...
}
<some stuff>
for(i = 3; i < 32; ++i){
...
}
Ces situations nécessitent plus que ma procédure. Le développeur devra analyser le code pour déterminer ce qu'il doit faire.
Mais la première étape consiste à trouver la première utilisation. Vous pouvez le faire visuellement, mais parfois, il est simplement plus facile de supprimer la déclaration, d'essayer de la compiler et de la remettre au-dessus de la première utilisation. Si cette première utilisation est à l'intérieur d'une instruction if, mettez-la là et vérifiez si elle se compile. Le compilateur identifiera ensuite d'autres utilisations. Essayez de créer un bloc de portée qui englobe les deux utilisations.
Une fois cette partie mécanique terminée, il devient plus facile d'analyser où se trouvent les données. Si une variable est utilisée dans un gros bloc de portée, analysez la situation et voyez si vous utilisez simplement la même variable pour deux choses différentes (comme un "i" qui s'utilise pour deux boucles for). Si les utilisations ne sont pas liées, créez de nouvelles variables pour chacune de ces utilisations non liées.