Pourquoi les boucles (;;) se comportent-elles comme des boucles infinies?

Les réponses à une question récente sur les boucles for(;;){} ( que fait une boucle for (;;) ) ne semblent pas répondre à quelque chose pour moi, alors j’ai pensé que j’essaierais d’affiner un peu la question. En particulier, au-delà de savoir que les boucles sans conditionnelles sont des boucles infinies, j’aimerais savoir pourquoi ce sont des boucles infinies.

Dans l’instruction for (;_;){} , le _ est une expression conditionnelle. Ma première hypothèse serait qu’une expression vide pourrait être évaluée à 0 ou à NULL . Mais si vous testez:

 for (;;){} 

est une boucle infinie, comme chacun l’a souligné.

 for (;1;){} 

est une boucle infinie.

Mais aucun de ces corps de boucle ne s’exécute du tout:

 for (;0;){} for (;NULL;){} 

Ainsi, l’expression conditionnelle vide ne semble pas être évaluée à 0 ni à NULL .

Donc, ma question est la suivante: le comportement de la boucle for (;;){} est-il un artefact de la façon dont C évalue les expressions, ou s’agit-il simplement d’un cas spécial défini par l’implémentation, car un corps de boucle qui ne s’exécute jamais n’est pas très utile ?

MISE À JOUR: Après avoir lu les commentaires et les réponses, je me rends compte que ma question n’était pas aussi clairement formulée qu’elle aurait pu être. Je suppose que la question était double:

  1. Le comportement des boucles for(;;){} ssortingctement le résultat de la façon dont C évalue les expressions en général ou ce comportement est-il spécifique à la façon dont C évalue les instructions? Il s’avère que la deuxième de ces solutions est la bonne et qu’après reflection, cela n’a plus de sens. Généralement, une expression manquante déclenche une erreur du compilateur. Par exemple, while(){} ne comstackra pas.

  2. Pourquoi ce comportement a-t-il été choisi for boucles sans expressions conditionnelles? Au départ, j’avais suggéré qu’il n’était tout simplement pas très utile d’avoir une boucle for avec un corps qui ne s’exécute jamais. Mais il me semble que, si vous laissez par erreur le conditionnel dans votre déclaration for , conformément aux règles de la norme, votre programme tombera probablement dans une boucle infinie. Cela peut paraître surprenant, mais au moins vous savez où il s’est écrasé. Mais si le comportement alternatif était la règle, votre programme omettrait le corps du, ce qui pourrait éventuellement donner lieu à de très mauvaises sursockets qui-sait-où. Ainsi, en appliquant le principe de la moindre surprise, le comportement en boucle infinie est plus souhaitable. Comme @martin l’a souligné, il ne s’agit que d’un paramètre par défaut raisonnable for boucles for .

Merci à tous pour vos commentaires et réponses, et pour m’aider à clarifier ma question moi-même.

C et C ++ garantissent tous deux ce comportement.


[C99: 6.8.5.3/1]: Les clauses-1 et expression-3 peuvent être omises. Une expression omise -2 est remplacée par une constante non nulle.


[C++14: 6.5.3/1]: L’instruction for

 for ( for-init-statement conditionopt; expressionopt) statement 

est équivalent à

 { for-init-statement while ( condition ) { statement expression ; } } 

[..]

[C++14: 6.5.3/2]: La condition et l’expression peuvent être omises, ou les deux. Une condition manquante rend la clause while implicite équivalente à while(true) .

L’expression conditionnelle vérifie si la boucle doit être poursuivie , oui, et la fonction par défaut d’une boucle est .. to loop. S’il ne s’agissait pas d’un cas particulier ayant une expression de test vide et continuant la boucle dans ce cas, il s’agirait par conséquent du cas contraire (comme vous l’avez déjà noté) et annulez la boucle, ce qui rend l’ensemble for déclaration moins puissant, voire redondant.

La technique utilisée ici s’appelle les défauts raisonnables / raisonnables.