2010-11-05 5 views
8

Dernièrement, j'ai vu beaucoup de questions posées sur la sortie de certaines instructions de code fous mais syntaxiquement autorisés comme i = ++i + 1 et i=(i,i++,i)+1;. Franchement parlant, pratiquement personne n'écrit un tel code dans la programmation actuelle. Pour être franc, je n'ai jamais rencontré un tel code dans mon expérience professionnelle. Donc, je finis généralement par sauter de telles questions ici sur SO. Mais dernièrement, le volume de tels Q demandés me fait penser si je rate une théorie importante en omettant de tels Q. Je comprends que les Q de ce genre tournent autour de Sequence points. Je ne sais presque rien sur les points de séquence pour être franc et je me demande simplement si le fait de ne pas le savoir est un handicap d'une manière ou d'une autre. Donc, quelqu'un peut-il s'il vous plaît expliquer la théorie/concept de Sequence points, ou si possible pointer vers une ressource qui explique sur le concept. Aussi, vaut-il la peine d'investir du temps dans la connaissance de ce concept/théorie?Une explication sur les points de séquence

+3

L'article de Steve Summit [ici] (http://c-faq.com/expr/seqpoints.html) serait utile. –

+3

Lisez la section 1.9 et l'introduction à la section 5 (c'est-à-dire avant 5.1). –

Répondre

5

La réponse la plus simple que je peux penser est:

C++ est définie en termes d'une machine abstraite. La sortie d'un programme exécuté sur la machine abstraite est définie UNIQUEMENT en fonction de l'ordre dans lequel les «effets secondaires» sont exécutés. Et les effets secondaires sont définis comme des appels dans les fonctions de la bibliothèque IO et des modifications apportées aux variables marquées comme volatiles.

Les compilateurs C++ sont autorisés à faire tout ce qu'ils veulent en interne pour optimiser le code, mais ils ne peuvent pas changer l'ordre des écritures en variables volatiles et en appels io.

Les points de séquence définissent les effets de pulsation du programme c/C++ avant que le point de séquence ne soit "terminé" et les effets secondaires après le point de séquence n'ont pas encore eu lieu. Mais, les effets secondaires (ou, code qui peut effectuer un effet secondaire indirectement (au sein un point de séquence peut être réorganisée.

Ce qui est pourquoi leur compréhension est importante. Sans cette compréhension, votre compréhension fondamentale de ce qu'est un C++ programme est (et comment il pourrait être optimisé par un compilateur agressif) est défectueux.

2

Voir http://en.wikipedia.org/wiki/Sequence_point.

C'est un concept assez simple, de sorte que vous n'avez pas besoin d'investir beaucoup de temps :)

+4

Je ne suis pas d'accord sur le fait que ce soit un concept simple, d'après ce que j'ai vu dans les discussions et les explications, il semble être un concept assez difficile à saisir, ou peut-être, c'est juste difficile pour moi! –

+0

Regardez l'article Wikipedia. La première phrase définit fondamentalement le concept. Il y a beaucoup de détails sur où la séquence se produit en C++, mais ce n'est pas sur le concept. –

1

Il faut savoir que les points de séquence existent parce que si vous ne savez pas sur eux, vous pouvez facilement écrire du code qui semble pour fonctionner correctement dans les tests, mais est en fait indéfini et peut échouer lorsque vous l'exécutez sur un autre ordinateur ou avec différentes options de compilation. En particulier si vous écrivez par exemple x++ dans le cadre d'une expression plus grande qui comprend également x vous pouvez facilement rencontrer des problèmes.

Je ne pense pas qu'il est nécessaire d'apprendre toutes les règles entièrement - mais vous devez savoir quand vous avez besoin de vérifier la spécification, ou peut-être mieux - quand réécrire votre code pour que vous ne soyez pas s'appuyer sur des règles de points de séquence si un design plus simple fonctionnerait aussi.

+0

Je sais que c'est assez subjectif à poser, mais savoir combien c'est savoir assez? Quelles sont les règles que l'on DOIT/ATLEAST savoir? –

0
int n,n_squared; 
for(n=n_squared=0;n<100;n_squared+=n+ ++n) 
printf("%i squared might or might not be %i\n",n,n_squared); 

... ne fait pas toujours ce que vous pensez qu'il va faire. Cela peut rendre le débogage douloureux. La raison est le ++ n récupère, modifie et stocke la valeur de n, qui pourrait être avant ou après que n soit récupéré.Par conséquent, la valeur de n_squared n'est pas clairement définie après la première itération. Les points de séquence garantissent que les sous-expressions sont évaluées dans l'ordre.

2

Les détails techniques précis des points de séquence peuvent devenir poilus, oui.Mais suivant ces lignes directrices résout presque toutes les questions pratiques:

  • Si une expression modifie une valeur, il doit y avoir un point de séquence entre la modification et toute autre utilisation de cette valeur.
  • Si vous n'êtes pas sûr que deux utilisations d'une valeur soient séparées par un point de séquence, divisez votre code en plusieurs instructions.

ici "modification" inclut les opérations d'affectation de la valeur à la main gauche dans =, +=, etc., ainsi que les ++x, x++, --x et x-- syntaxes. (Il est généralement ces incrément/expressions décrémentation où certaines personnes tentent d'être intelligent et finissent par avoir des ennuis.)

Heureusement, il y a des points de séquence dans la plupart des endroits « attendus »:

  • Au fin de chaque déclaration ou déclaration.
  • Au début et à la fin de chaque appel de fonction.
  • Aux opérateurs intégrés && et ||. Au numéro ? dans une expression ternaire.
  • À l'opérateur de virgule , intégré. (Le plus souvent vu dans pour les conditions, par exemple for (a=0, b=0; a<m && b<n; ++a, ++b).) Une virgule qui sépare les arguments de fonction est pas l'opérateur de virgule et est pas un point de séquence.

Surchargé operator&&, operator|| et operator, ne causent pas de points de séquence. Les surprises potentielles de ce fait est l'une des raisons pour lesquelles les surcharger est généralement découragé.

Questions connexes