On ne fait pas de la magie

«Toute technologie suffisamment avancée est indiscernable de la magie.» Arthur C. Clarke

Le piège des analogies entre les langages

Lors des formations que j’anime, j’essaie d’utiliser les connaissances et les habitudes des apprenants pour leur faire comprendre les nouveaux concepts. Par exemple, je peux utiliser du code qu’ils lisent aisément en C ou C++, issu d’une formation C++, pour leur montrer comment l’écrire en Fortran.

Il est important de bien expliquer les différences entre les langages lorsqu’on utilise cette approche.

Exemple avec l’attribut static (C/C++) et l’attribut save (Fortran)

L’attribut static du C ou l’attribut save du Fortran ont le même effet : rendre la variable à laquelle il est appliqué permanente. Ce n’est plus une variable automatique, créée au début d’une fonction et détruite à la fin de cette fonction. C’est une variable créée une seule fois dans l’exécution du programme, dont la valeur se maintient d’un appel à l’autre de la fonction.

En C++, un exemple serait

void affiche_static()
{
    static int i = 42;
    cout << "Affiche avec static " << i << endl;
    i++;
}

Voici une transcription en Fortran

subroutine affiche_static()
integer, save :: i = 42
print*,  "Affiche avec static ", i
i = i + 1
end subroutine affiche_static

On peut tester ces exemples avec un programme simple, en écrivant des fonctions affiche_automatic, en enlevant simplement le static et le save. Cela donne ces deux exemples de codes, que vous pouvez tester en ligne sur onlinegdb.com

Code C++ complet

#include <iostream>
using namespace std;
void affiche_static();
void affiche_automatic();
int main() {
   affiche_static();
   affiche_static();
   affiche_automatic();
   affiche_automatic();
}

void affiche_static()
{
    static int i = 42;
    cout << "Affiche avec static " << i << endl;
    i++;
}

void affiche_automatic()
{
    int i = 42;
    cout << "Affiche sans static " << i << endl;
    i++;
}

Code Fortran complet

program demo2
   call affiche_static();
   call affiche_static();
   call affiche_automatic();
   call affiche_automatic();
end program demo2
subroutine affiche_static()
integer, save :: i = 42
print*,  "Affiche avec static ", i
i = i + 1
end subroutine affiche_static
subroutine affiche_automatic()
integer :: i
i = 42
print*,  "Affiche sans static ", i
i = i + 1
end subroutine affiche_automatic

Si vous suivez ce lien, et lancez l’exécution du code, vous obtenez le résultat attendu :

C++
Affiche avec static 42
Affiche avec static 43
Affiche sans static 42
Affiche sans static 42
Fortran
 Affiche avec static           42
 Affiche avec static           43
 Affiche sans static           42
 Affiche sans static           42

Limites de cette approche

Lors d’une formation, j’attends normalement, après avoir présenté cet exemple, une remarque sur ces lignes :

integer :: i
i = 42

Il semblerait plus simple d’écrire, comme en C++:

integer :: i = 42

L’un des avantages des exemples sur onlinegdb.com est qu’il est simple d’en faire une copie avec le bouton « Fork this » pour modifier le code. Cela donne un nouveau projet dans lequel j’ai modifié le sous-programme affiche_automatic :

subroutine affiche_automatic()
integer :: i = 42
print*,  "Affiche sans static ", i
i = i + 1
end subroutine affiche_automatic

En exécutant le code, on obtient le résultat suivant :

C++
Affiche avec static 42
Affiche avec static 43
Affiche sans static 42
Affiche sans static 42
Fortran
 Affiche avec static           42
 Affiche avec static           43
 Affiche sans static           42
 Affiche sans static           43

En regardant les résultats, on a la surprise de voir que le sous-programme affiche_automatic se comporte comme affiche_static !

La norme Fortran indique en effet qu’une variable initialisée, comme dans l’instruction integer :: i = 42 est automatiquement une variable save, comme nous le constatons dans le résultat des tests.

C’est une des limites de l’approche dont je parlais : il faut faire très attention à ne pas transcrire automatiquement les instructions d’un langage dans un autre et veiller à bien présenter les constructions spécifiques du langage étudié.

Une autre limite est de bien estimer les connaissances préalables des apprenants. Il faut être sûr qu’ils connaissent bien la construction sur laquelle on se base pour effectuer la comparaison. Dans notre cas, s’ils ne connaissent pas bien l’effet de l’instruction static en C++, on aura plus compliqué l’apprentissage qu’autre chose.

Commentaires

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *