Continuons cette série avec une surprise tout droit sortie de C++98 !
Pendant mes pluvieuses vacances d’été, j’ai découvert un recoin du langage C++, version 98, qui m’a surpris par sa simplicité et son... (in)utilisation. Rien à voir avec les règles de déclaration d’un tableau de pointeur de fonctions, renvoyant elles-mêmes un pointeur de fonction (car oui, void (*(f(void)))(void) { return 0;} est une déclaration de fonction valide), on va plutôt parler d’une structure de contrôle ultra connue, une construction pour laquelle on ne soupçonnerait pas l’existence d’un quelconque recoin du langage : la bonne vieille boucle for.
Sans plus de circonvolution inutile, je vous livre le bijou :
Eh oui, en C++, cette construction est valide depuis... toujours. Ce n’est pas le cas en C, quelle que soit sa version. Si au premier abord, on peut difficilement lui prêter un usage, cette construction n’est pas sans rappeler une construction voisine :
qui est bien plus répandue, et que l’on retrouve souvent avec des objets plus complexes qui possèdent un operator bool(). Par symétrie, on comprend alors l’extension de cette construction à la condition d’une boucle for, et on n’est pas surpris de trouver :
qui fonctionne sur le même principe. Dans les trois cas, la portée de la variable déclarée dans la condition est limitée au corps de la boucle ou aux deux branches du test. La construction do ... while(int i = check(j)) ; est aux abonnés absents, mais cela n’est pas bien surprenant au regard de l’ordre lexicographique (d’ailleurs, saviez-vous que do ; while(1) ; était valide, même en ANSI C ?).
Tous les objets ne possèdent pas un opérateur de conversion vers un boolean, et on peut avoir besoin d’expliciter la condition, tout en conservant les avantages des règles de portée liées à la déclaration d’une variable dans la condition. Depuis la version C++17, il est possible de précéder la condition d’une déclaration :
Pas de construction similaire pour la boucle for, à moins d’utiliser un range-for qui autorise depuis C++20 la forme :
Comme quoi, la déclaration d’une variable dans une condition est une idée qui a fait son chemin !
P.S. : La déclaration de l’introduction est une façon valide depuis C ANSI de déclarer une fonction qui ne prend pas de paramètre et renvoie un pointeur vers une fonction qui ne prend pas de paramètre et ne renvoie rien ;-).