web-dev-qa-db-fra.com

Pourquoi S :: x n'est-il pas utilisé?

Considérez cet exemple de cppreference :

struct S { static const int x = 1; };
void f() { &S::x; } // discarded-value expression does not odr-use S::x

Je suis d'accord que &S::x est une expression de valeur supprimée, puisque la norme dit (9.2, paragraphe 1 [stmt.expr] de n47 )

Les énoncés d'expression ont la forme

expression-statement:
    expression_opt ;

L'expression est une expression à valeur rejetée (article 8) ...

Cependant, est-ce suffisant pour S::x ne pas être odr-used? 6.2, paragraphe 3 [basic.def.odr] stipule

Une variable x dont le nom apparaît comme une expression potentiellement évaluée ex est odr-used par ex sauf si

  • ...
  • si x est un objet, ex est un élément de l'ensemble des résultats potentiels d'une expression e, où soit
    • la conversion lvalue-to-rvalue (7.1) est appliquée à e, ou
    • e est une expression à valeur rejetée (article 8) .

Le problème est que l'expression de valeur supprimée &S::x n'a aucun résultat potentiel (ce qui signifie que S::x n'est pas le résultat potentiel de &S::x), comme vous pouvez le voir dans 6.2, paragraphe 2 [basic.def.odr]:

... L'ensemble des résultats potentiels d'une expression e est défini comme suit:

  • Si e est une expression id (8.1.4), l'ensemble contient uniquement e.
  • Si e est une opération d'indexation (8.2.1) avec un opérande de tableau, l'ensemble contient les résultats potentiels de cet opérande.
  • ...
  • Sinon, l'ensemble est vide.

Ensuite, comment pouvez-vous expliquer que S::x n'est pas utilisé?

51
b1sub

Il est en effet un peu utilisé. Votre analyse est correcte (et j'ai corrigé cet exemple il y a quelque temps ).

4
T.C.

Oui, dans l'exemple, &S::x odr utilise S::x.

[basic.def.odr]/4

Une variable x dont le nom apparaît comme une expression potentiellement évaluée ex est odr-used par ex à moins d'appliquer la valeur-à-l La conversion de rvalue en x donne une expression constante qui n'invoque aucune fonction non triviale et, si x est un objet, ex est un élément de l'ensemble des résultats potentiels d'une expression e, où soit la conversion de lvalue en rvalue est appliquée à e, soit e est une expression de valeur rejetée.

L'adresse d'un objet n'est jamais une expression constante. C'est pourquoi S::x est utilisé dans &S::x.

Pour justifier cette dernière affirmation:

[expr.const]/6

Une expression constante est soit une expression constante de noyau glvalue qui fait référence à une entité qui est le résultat autorisé d'une expression constante (telle que définie ci-dessous), soit une expression constante de noyau prvalue dont la valeur satisfait les contraintes suivantes [...]

et

[expr.const]/2.7

2) Une expression e est une expression constante de base sauf si l'évaluation de e, suit les règles de l'abstrait machine , évaluerait l'une des expressions suivantes:
[...]
2.7) une conversion de lvalue en rvalue à moins qu'elle ne soit appliquée à

(aucun des points suivants ne s'applique :)

2.7.1) une valeur gl non volatile de type intégral ou énumération qui fait référence à un objet const complet non volatil avec une initialisation précédente, initialisé avec une expression constante, ou
2.7.2) une valeur gl non volatile qui fait référence à un sous-objet d'un littéral de chaîne, ou
2.7.3) une valeur gl non volatile qui fait référence à un objet non volatil défini avec constexpr, ou qui fait référence à un sous-objet non mutable d'un tel objet, ou
2.7.4) une valeur gl non volatile de type littéral qui se réfère à un objet non volatile dont la durée de vie a commencé dans le cadre de l'évaluation de e;

0
YSC