Maison >développement back-end >C++ >Est-ce que `i = i` appelle un comportement non défini avec des types définis par l'utilisateur en C ?

Est-ce que `i = i` appelle un comportement non défini avec des types définis par l'utilisateur en C ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-12-05 10:36:15817parcourir

Does `i  =   i` Invoke Undefined Behavior with User-Defined Types in C  ?

Le comportement non défini revisité : points de séquence et types définis par l'utilisateur

La question :

Dans un article précédent sur le comportement indéfini et les points de séquence, l'expression i = i était censée invoquer un comportement indéfini pour les types intégrés. Cependant, la question se pose : et si le type de i était défini par l’utilisateur ? Plus précisément, supposons que nous ayons un index de classe avec des opérateurs surchargés.

La réponse : comportement non défini vs comportement bien défini

Contrairement à l'intuition, il s'avère que le l'expression i = i n'invoque pas de comportement non défini pour les types définis par l'utilisateur comme Index. En effet, les opérateurs surchargés dans Index sont considérés comme des fonctions. Selon la norme C ISO, l'évaluation d'une fonction introduit un point de séquence après l'évaluation des arguments de la fonction, et un autre après la copie de la valeur renvoyée.

Points de séquence et opérateurs surchargés

Dans le cas de i = i, l'expression i est évaluée avant d'être passée en argument à l'opérateur =. Cela signifie qu'il y a un point de séquence après l'évaluation de i, garantissant que l'objet i n'est modifié qu'une seule fois entre des points de séquence consécutifs.

Par conséquent, l'expression i = i pour les types définis par l'utilisateur comme Index est équivalente à écrire i.operator =(i.operator ());, qui est une expression bien définie sans comportement indéfini. Il en va de même pour l'expression syntaxiquement plus simple i.add(i.inc());.

Une distinction subtile :

Il est important de noter que i = i n'est pas une expression au sens de la grammaire C. Il s'agit plutôt d'une « expression d'instruction », qui est une combinaison syntaxique d'une expression et d'une instruction. Les expressions d'instruction sont exécutées comme des instructions normales, mais leur résultat peut également être affecté à une variable.

Comportement de a[ i] = i

Si a est un tableau d'un type intégré, l'expression a[ i] = i invoque un comportement indéfini car la lvalue a[ i] est évaluée deux fois : une fois dans l'expression i et de nouveau dans l'affectation i = i.

Cependant, si a est un type défini par l'utilisateur qui surcharge l'opérateur d'indice, l'expression peut se comporter différemment selon l'implémentation de l'opérateur d'indice. Par exemple, si l'opérateur d'indice est implémenté à l'aide de l'opérateur const Index&[](Index i), alors l'expression sera bien définie car la lvalue a[ i] n'est évaluée qu'une seule fois, avant que l'opérateur d'indice ne soit appelé.

La validité de i;

L'expression je; est bien défini en C 03, car il est équivalent à ((i.operator ()).operator ()).operator (). En effet, chaque opérateur introduit un point de séquence, garantissant que l'objet i n'est modifié qu'une seule fois entre des points de séquence consécutifs.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn