Les codes fantastiques : C for surprenant

Magazine
Marque
GNU/Linux Magazine
Numéro
269
Mois de parution
mai 2024
Spécialité(s)


Résumé

Continuons cette série avec une surprise tout droit sortie de C++98 !


Body

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 :

for(int i = 0; int res = check(i); ++i)
    something(res);

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 :

if(int res = check(i))
    something(res) ;

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 :

while(int res = check(i))
    something(res) ;

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 :

if(int res = check(i) ; res > 1)
    something_else(res) ;

Pas de construction similaire pour la boucle for, à moins d’utiliser un range-for qui autorise depuis C++20 la forme :

for(auto some = create() ; auto content : some)
    stuff(content) ;

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 ;-).



Article rédigé par

Abonnez-vous maintenant

et profitez de tous les contenus en illimité

Je découvre les offres

Déjà abonné ? Connectez-vous