Point de séquence après une déclaration de retour?

Dans ma réponse à une question ici, j’ai expliqué ce qui s’est passé lorsque postfix ++ était utilisé sur une variable globale sur la même ligne qu’une instruction return .

L’annexe informative C de C11 indique l’existence d’un sharepoint séquence immédiatement après un return et renvoie au chapitre normatif 6.8.6.4, dans lequel aucun texte relatif aux points de séquence ne peut être trouvé.

Où dans la norme C puis-je trouver un texte normatif indiquant qu’il y a un sharepoint séquence après une instruction return ?

(Je n’ai trouvé qu’un texte normatif indiquant cela pour les fonctions de bibliothèque, en tant que cas particulier, à 7.1.4 / 3.)

C 2011 (draft n1570) 6.8 4: «Chacune des expressions suivantes est une expression complète:… l’expression (facultative) dans une instruction return . Il y a un sharepoint séquence entre l’évaluation d’une expression complète et l’évaluation de la prochaine expression complète à évaluer. ”

Donc techniquement, le sharepoint séquence ne se trouve pas après un retour mais entre l’évaluation de l’expression du retour et l’expression suivante. Considérons ce code, appelé quand a est initialement 0:

 int a = 0; int Foo(void) { return a++; } void Bar(void) { int b = Foo() + a; … } 

Dans Foo() + a , si Foo() ou a est évalué en premier n’est pas spécifié. Nous allons considérer les deux ordres à la lumière des deux règles potentielles (sharepoint séquence après retour par rapport au sharepoint séquence entre l’expression du retour et la prochaine expression complète). Si l’implémentation fait a première, alors il faut faire:

 a Sequence point Foo() + 

et ensuite, une autre expression complète suivrait, de sorte que, quelle que soit la règle, il y aurait un sharepoint séquence, et ce code est identique dans les deux cas, en ce qui nous concerne. Le résultat est que b est défini sur 0.

Si l’implémentation Foo() abord Foo() , alors, avec la règle du «pointeur de séquence après un retour », l’implémentation doit effectuer:

 Sequence point Foo() Sequence point a + 

Ce code aurait un comportement défini: a est incrémenté de l’effet secondaire dans Foo , et est terminé avant l’access, puis + est exécuté. Le résultat est que a est défini sur 1. Bien que le résultat puisse être 0 ou 1 avec cette règle de «sharepoint séquence après retour », il est simplement indéterminé lequel des deux ordres est utilisé; le comportement n’est pas complètement indéfini.

Cependant, si l’implémentation utilise d’abord Foo() et utilise la règle C standard de «sharepoint séquence entre l’expression d’un retour et l’expression complète suivante», nous avons:

 Sequence point Foo() ??? a ??? + ??? 

La marque «???» marque les endroits où le sharepoint séquence requirejs peut être placé n’importe où après le retour et avant la prochaine expression complète. Dans ce cas, la valeur de a peut être accédée dans a et modifiée dans Foo() , et il n’y a pas de sharepoint séquence intermédiaire. C’est un comportement indéfini.

Par conséquent, la règle «sharepoint séquence après l’expression d’un retour et avant la prochaine expression complète» est différente de «sharepoint séquence immédiatement après un retour »; le premier a un comportement indéfini dans cet exemple, et le second pas.

Je ne pense pas que vous allez trouver ce que vous cherchez. no text regarding sequence points can be found qui est vrai, il est seulement impliqué par la section 6.8 p4.

La norme C ++ (ISO / IEC 14882: 2003) de la section 1.9 (note de bas de page 11) indique le fait qu’un sharepoint séquence après la déclaration n’est pas explicitement écrit nulle part dans les normes C:

11) Le sharepoint séquence au retour de fonction n’est pas spécifié explicitement dans ISO C et peut être considéré comme redondant avec les points de séquence dans les expressions complètes, mais la clarté supplémentaire est importante dans C ++. En C ++, une fonction appelée peut mettre fin à son exécution de plusieurs manières, telles que le lancement d’une exception.