But de while (1); énoncé en C

à quoi sert while(1); ? Je suis conscient while(1) (pas de point-virgule) Boucles infiniment et est similaire à une situation de spinlock. Cependant, je ne vois pas où while(1); pourrait être utilisé ?

code échantillon

if(!condition)
{ 
  while(1);
}

Note: il ne s'agit pas d'un cas de do - while() ou de while(1) .

52
demandé sur Abhijit K Rao 2014-06-18 10:45:52

12 réponses

veuillez noter que tous les énoncés valides de la langue ne pas avoir à servir une fin. Ils sont valables pour la grammaire de la langue. On peut construire beaucoup d'énoncés similaires "inutiles", tels que if (1); . Je vois de telles déclarations comme la conjonction d'un conditionnel ( if , while , etc.) et la déclaration vide ; (qui est aussi une déclaration valide bien qu'elle ne serve évidemment pas de but spécifique).

que cela dit, j'ai trouvé while (1); dans le code de sécurité. Quand l'utilisateur fait quelque chose de très mauvais avec un appareil intégré, il peut être bon de les empêcher d'essayer autre chose. Avec while (1); , nous pouvons bloquer inconditionnellement un appareil jusqu'à ce qu'un opérateur accrédité le redémarre manuellement.

while(1); peut aussi faire partie de l'implémentation d'une panique du noyau, bien qu'une boucle for(;;) {} semble être une façon plus courante d'exprimer la boucle infinie, et il pourrait y avoir une corps non vide (par exemple pour panic_blink() ).

86
répondu dureuill 2014-06-19 04:38:17

si vous creusez jusqu'à l'assemblage, (c'est plus facile à saisir du point de vue des systèmes embarqués, ou si vous avez essayé de programmer un bootloader)

vous réaliserez qu'une boucle while n'est qu'une instruction jmp ... c'est à dire

(pseudo code: starting loop address)
add ax, bx
add ax, cx
cmp ax, dx
jz  (pseudo code: another address location)
jmp (pseudo code: starting loop address)

permet d'expliquer comment cela fonctionne, le processeur continuera à exécuter les instructions de façon séquentielle ... n'importe quoi. Donc au moment où il entre dans cette boucle, il va ajouter register bx à ax et stocker dans ax, ajouter register CX à ax and store to ax, cmp ax, dx (cela signifie soustraire dx de ax) l'instruction jz signifie Sauter à (un autre emplacement d'adresse) si le drapeau Zéro est défini (qui est un peu dans le registre des drapeaux qui sera défini si le résultat de la soustraction ci-dessus est zéro), puis jmp à l'adresse de boucle de démarrage (assez simple) et de refaire le tout.

la raison pour laquelle je vous ai ennuyé avec toute cette assemblée est de vous montrer que cela se traduirait en C par

int A,B,C,D;
// initialize to what ever;

while(true)
{
A = A + B;
A = A + C;

if((A-D)==0)
{break;}

}

// if((X-Y)==0){break;} is the 
// cmp ax, dx
// jz  (pseudo code: another address location)

alors imaginez le senario dans assembly si vous aviez juste une très longue liste d'instructions qui ne s'est pas terminée avec un JMP (la boucle while) pour répéter une section ou charger un nouveau programme ou faire quelque chose ... Finalement, le processeur va atteindre la dernière instruction et ensuite charger l'instruction suivante pour ne rien trouver (il va alors geler ou triple faute ou quelque chose).

C'est exactement pourquoi, quand vous voulez que le programme ne fasse rien jusqu'à ce qu'un événement soit déclenché, vous devez utilisez une boucle while(1), pour que le processeur continue de sauter à sa place et n'atteigne pas cette adresse d'instruction vide. Lorsque l'événement est déclenché, il saute à l'adresse d'instructions du gestionnaire d'événements, l'exécute, efface l'interruption et retourne à votre boucle while(1) juste en sautant à sa place en attendant d'autres interruptions. Btw le while(1) est appelé un superloop si vous voulez en savoir plus sur elle ... Juste pour celui qui est démangeaisons insanely de discuter et de commenter négativement à ce point, ce est pas une assemblée tutoriel ou une conférence ou quoi que ce soit. C'est juste une explication en anglais simple qui est aussi simple que possible, en négligeant beaucoup de détails sous-jacents comme des pointeurs et des piles et ainsi de suite et dans certains cas sur la simplification des choses pour obtenir un point à travers. Personne ne cherche la précision de la documentation ici et je sais que ce code C ne sera pas compilé comme ça, mais c'est seulement pour la démo !!

29
répondu a.atlam 2014-06-22 19:43:46

c'est marqué C, mais je vais commencer avec une perspective C++. En C++11, le compilateur est libre d'optimiser while(1); .

du projet de norme C++11 n3092, section 6.5, paragraphe 5 (soulignement ajouté):

Une boucle qui, à l'extérieur de l'initialisation de l'instruction dans le cas d'une instruction for,

- ne fait aucun appel aux fonctions d'E/S de la bibliothèque, et

- ne pas accéder ou de modifier les volatilité des objets, et

- n'effectue pas d'opérations de synchronisation (1.10) ou d'opérations atomiques (Clause 29)

on peut supposer que la mise en œuvre prendra fin. [ Note: Ceci est destiné à permettre des transformations de compilateurs, telles que la suppression de boucles vides, même lorsque la terminaison ne peut pas être prouvée. - fin de la remarque ]



La norme C11 a une entrée similaire, mais avec une différence essentielle. Extrait du projet de norme C11 n1570, (souligné par moi):

un énoncé d'itération dont l'expression de contrôle n'est pas une expression constante , 156) qui n'effectue aucune opération d'entrée/sortie, n'accède pas à des objets volatils et n'effectue aucune opération de synchronisation ou d'opération atomique dans son corps, contrôlant l'expression, ou (dans le cas d'Un for statement) son expression -3 , peut être considéré par la mise en œuvre de mettre fin. 157)

156) une expression de contrôle omise est remplacée par une constante non nulle, qui est une expression constante.

157) Ceci est destiné à permettre des transformations de compilateurs telles que la suppression de boucles vides même lorsque la terminaison ne peut pas être prouvée.



Ce signifie while(1); peut être supposé se terminer en C++11 mais pas en C11. Malgré cela, la note 157 (non contraignante) est interprétée par certains vendeurs comme leur permettant de supprimer cette boucle vide. La différence entre while(1); en C++11 et C11 est celle du comportement défini versus non défini. Comme la boucle est vide, elle peut être supprimée en C++11. Dans C11, while(1); est provably non-terminating, et c'est un comportement non défini. Puisque le programmeur a invoqué UB, le compilateur est libre de faire n'importe quoi, y compris supprimer cette boucle offensante.

il y a eu un certain nombre de discussions sur l'optimisation des compilateurs en supprimant while(1); . Par exemple, est-ce que les compilateurs sont autorisés à éliminer les boucles infinies? , est-ce qu'un vide pour boucle utilisé comme un sommeil sera optimisé ailleurs? , Optimisation de loin un "while(1);" dans C++0x . Notez que les deux premiers étaient spécifiques au C.

18
répondu David Hammen 2017-05-23 12:09:39

je suppose que le while(1); n'est pas associé à une boucle do ...

la seule implémentation semi-utile de while(1); que j'ai vu est une boucle" do-nothing " en attente d'une interruption; comme un processus parent en attente D'un SIGCHLD, indiquant qu'un processus enfant est terminé. Le handler SIGCHLD du parent, une fois que tous les processus enfant sont terminés, peut terminer le thread parent.

il fait l'affaire, mais gaspille beaucoup de CPU-time. Une telle utilisation devrait peut-être effectuer une sorte de sommeil à abandonner le processeur périodiquement.

8
répondu Mahonri Moriancumer 2014-06-18 07:08:55

une utilisation sur les logiciels embarqués est de mettre en œuvre un logiciel réinitialisé en utilisant le chien de garde:

while (1);

ou l'équivalent, mais plus sûr, car il rend l'objectif plus clair:

do { /* nothing, let's the dog bite */ } while (1);

si le chien de garde est activé et n'est pas accusé de réception après x millisecondes nous savons qu'il va réinitialiser le processeur donc utilisez ceci pour mettre en œuvre une réinitialisation du logiciel.

8
répondu ouah 2014-06-18 11:39:42

un endroit que j'ai vu un while(1); est dans la programmation intégrée.

l'architecture a utilisé un thread principal pour surveiller les événements et les threads ouvriers pour les gérer. Il y avait une minuterie de surveillance matérielle (explication ici ) qui effectuerait une remise à zéro du module après une période de temps. Dans la boucle de sondage du thread principal, il réinitialiserait cette minuterie. Si le thread principal détectait une erreur non récupérable, un while(1); serait utilisé pour attacher le fil principal, ce qui déclenche la réinitialisation du chien de garde. Je crois qu'assert failure a aussi été mis en œuvre avec un while(1); .

5
répondu waldol1 2014-06-18 14:58:43

comme d'autres l'ont dit, c'est juste une boucle infinie qui ne fait rien, complètement analogue à

while (1) {
    /* Do nothing */
}

La boucle avec le point-virgule a un corps. Lorsqu'il est utilisé comme une instruction, un seul point-virgule est une instruction nulle , et le corps de la boucle se compose de cette instruction nulle.

pour la lisibilité, pour faire comprendre au lecteur que la déclaration nulle est le corps de la boucle, je recommande de l'écrire sur un séparé ligne:

while (1)
    ;

sinon il est facile de le manquer à la fin de la ligne "while", où il n'y a généralement pas de point-virgule, et le lecteur peut confondre la ligne suivante comme le corps de la boucle.

ou utilisez un énoncé composé vide à la place.

4
répondu Thomas Padron-McCarthy 2014-06-19 04:06:19
while(1);

est en fait très utile. Surtout quand c'est un programme qui a une sorte de code d'accès et que vous souhaitez désactiver l'utilisation du programme pour l'utilisateur, parce que, par exemple, il a entré le mauvais mot de passe pour 3 fois. L'utilisation d'un while(1); arrêterait la progression du programme et rien ne se produirait tant que le programme n'est pas redémarré, principalement pour des raisons de sécurité.

1
répondu Zach P 2014-06-18 08:09:31

cela peut être utilisé pour attendre interrompre . Fondamentalement, vous initialisez toutes les choses dont vous avez besoin et commencez à attendre que quelque chose se produise. Après cela une certaine fonction spécifique est appelée et exécutée, après cela elle retourne à l'état d'attente.

cette chose pourrait être bouton appuyé, clic de souris / mouvement, données reçues et etc.

ce qui est plus je dirais, similaire trucs est vraiment souvent utilisé par UI Framework. Pendant qu'il attend des signaux sur les actions des utilisateurs.

1
répondu ST3 2014-06-19 08:46:24

dans les chipsets AVR programmation (utilisant le langage de programmation C) cet énoncé est fréquemment utilisé, il joue un rôle comme boucle d'événement.

supposons que je veuille concevoir un compteur de comptage, donc je peux utiliser ce code pour l'implémenter:

void interrupt0() {
   /* check if key pressed, count up the counter */
}

void main() {
    /* Common inits */
    /* Enable interrupt capability and register its routine */

    /* Event loop */
    while(1);
} 
1
répondu Hi I'm Frogatto 2014-06-19 12:48:15

puisque la condition est toujours vraie, nous pouvons dire que nous utilisons une tautologie logique comme connu en mathématiques. Alors que la boucle prouve qu'elle est toujours vraie, elle ne cessera pas de boucler à moins d'être forcée par le code ou jusqu'à ce que les ressources se soient effondrées.

0
répondu newToStackOverflow 2014-06-19 20:40:13

je pense que la raison pour laquelle while(1); est utilisé est parce que plus tôt dans le code un EventHandler ou une interruption a été mis sur ce thread. L'utilisation du code de verrouillage de sécurité standard Thread peut être assez coûteuse (en temps) quand vous savez que votre code ne "attendra" qu'un temps très court. Par conséquent, vous pouvez configurer l'interruption et le "spin" en utilisant while(1); qui, bien qu'il soit une attente chargée (ne laisse pas le Idle/service CPU autres threads) prend très peu de cycles à configurer.

en résumé, c'est un spinlock' bon marché ' pendant que votre thread attend une interruption ou un événement.

0
répondu Th3Minstr3l 2014-06-25 10:04:44