8
votes

Appelle une fonction sur un pointeur null indéfini?


10 commentaires

Je ne pense pas qu'il y ait quelque chose dans la norme qui restreint, par exemple, implémentant toutes les fonctions membres via une recherche à la fourchette. Donc, dans une telle implémentation, vous seriez vraiment la déséroférance null (plutôt que de simplement relier de manière statique à A :: FOO ). Je ne peux pas fournir une citation standard, cependant.


La question est donc la suivante: "Qu'est-ce que la référence indique que vous ne pouvez pas dréerence un pointeur nul?"


Cet article a une analyse détaillée du sujet: Stackoverflow.com/Questtions/669742/...


@MOOINGDUCK NO. Je cherche la référence qui dit a-> x est équivalente à (* a) .x .


Related: Stackoverflow.com/Questions/5248877/...


@Joe c'est ce que j'ai dit. Je cherche la citation standard qui dit la partie sur le "sucre syntaxique".


Cette question précédemment répondue peut aider beaucoup: Stackoverflow.com/Questtions/669742/...


Une discussion approfondie de ce sujet est donnée [dans ce post] [1]. [1]: Stackoverflow.com/Questtions/2474018/...


@Scott: S'il vous plaît rejoindre moi dans dup-vote.


@Luchiangriggore Yeahiguit, regarde la mise à jour de ma réponse, comprend un lien vers un bon post avec une discussion sur ce sujet.


4 Réponses :


0
votes

Oui, c'est UB comme A n'a pas été initialisé pour pointer vers un emplacement de mémoire valide avant qu'il ne soit déréférencé.


4 commentaires

Je cherche une citation de la norme. Votre réponse ne fournit aucune information supplémentaire que moi déjà énoncée dans la question. PS Je n'ai pas non plus de bownvote.


@Luchiangriggore: Eh bien, c'est une connaissance assez courante que c'est UB, mais la norme n'est pas gratuite et je ne l'ai pas allongée.


Il y a des brouillons libres allongés, pas très différents que la version officielle.


@Luchiangriggore: OK, je devrais attraper un. J'oublie que les brouillons sont en réalité libre.



1
votes

Je suis au courant d'au moins un cas où cet idiome n'est pas seulement autorisé, mais compucié: MFC Classe CWND de Microsoft fournit une fonction de membre Getsafehwnd qui teste si ceci == null et retourne sans accès toutes variables de membre.

Bien sûr, il y a beaucoup de personnes qui prétendraient que MFC est un très mauvais exemple.

Peu importe si le comportement est indéfini ou non, dans la pratique, il n'est pas susceptible de se comporter mal. Le compilateur traitera a--> foo () comme A :: foo (a) qui ne fait pas une déréférence sur le site d'appel, tant que foo n'est pas virtuel.


2 commentaires

C'est la raison exacte que je demande. J'ai vu cela dans le code de production, je suppose que c'est UB, mais je veux aussi le prouver.


@Luchiangriggore, c'est une bonne question. La mise en œuvre de getsafehwnd m'a toujours rendu un peu nerveuse, même si je comprends pourquoi ça marche.



9
votes

Je recherche la référence indiquant a--> x est équivalent à (* a) .x . .

ici c'est:

[C ++ 11: 5.2.5 / 2]: pour la première option (point), la première expression doit avoir un type de classe complète. Pour la deuxième option (flèche), la première expression doit avoir un pointeur pour compléter le type de classe. L'expression E1-> E2 est convertie en forme équivalente (* (1)). E2 ; Le reste de 5.2.5 va aborder seule la première option (point). Dans les deux cas, l'expression id-expression doit nommer un membre de la classe ou de l'une de ses classes de base. [ Remarque: Parce que le nom d'une classe est inséré dans sa portée de classe (clause 9), le nom d'une classe est également considéré comme un membre imbriqué de cette classe. -end Note ] [ Remarque: 3.4.5 décrit comment les noms recherchent après le . et -> -> -> les opérateurs. -end note ]

Il n'y a pas de devis direct pour la déséroférance d'un pointeur nul étant UB, malheureusement. Vous pouvez trouver davantage dans cette question: Quand invoque une fonction de membre sur une instance null entraîne un comportement non défini?


2 commentaires

8.3.2 / 4 "Références"): Remarque: En particulier, une référence NULL ne peut pas exister dans un programme bien défini, car le seul moyen de créer une telle référence serait de le lier à "objet" obtenu par la déséroférance A pointeur null, qui provoque un comportement indéfini. Stackoverflow .com / questions / 2727834 / ...


@ 0A0D: C'est non normatif. Gman explore le sujet plus en détail dans le poste que je suis lié à, y compris citer le même passage non normatif que vous avez posté dans votre commentaire, mais vous allez plus loin avec un raisonnement équilibré. Je suggère de le lire.



0
votes

Il est couvert ici: http: // www .Open-std.org / jtc1 / sc22 / wg21 / docs / cwg_active.html # 232

Au moins quelques endroits de l'EST State cette indirection à travers un Null Pointer produit un comportement indéfini: 1.9 [INTRO.EXECUTION] Le paragraphe 4 donne "la déséroférance du pointeur null" comme exemple de comportement indéfini et 8.3.2 [dcl.ref] paragraphe 4 (dans une note) utilise ce comportement supposément non défini comme justification de la inexistance des "références nulles".

Cependant, 5.3.1 [Expr.unary.op] Paragraphe 1, qui décrit le "*" Opérateur, ne dit pas que le comportement n'est pas défini si le L'opérande est un pointeur nul, comme on peut s'attendre. En outre, au moins Un passage donne la désirficite d'un comportement bien défini par le pointeur NULL: 5.2.8 [EXPR.TYPEID] Paragraphe 2 dit

Si l'expression de lvalue est obtenue en appliquant l'opérateur unaire * à un pointeur et le pointeur est une valeur de pointeur nulle (4.10 [CONV.PTR]), l'expression typeid jette l'exception Bad_Typeid (18.7.3 [Bad.typeid]).

Ceci est incompatible et devrait être nettoyé.

En savoir plus sur le lien si vous voulez en savoir plus.


3 commentaires

C'est une bonne citation et très pertinent. Cependant, cela "couvre"; Cela est simplement convient que ceci est une question à laquelle il faut répondre; Cela ne répond pas en soi.


@LightnessRacsinorbit: Je ne vais pas plagier toute la page.


Si vous le faites, cela ne changerait rien. Les problèmes ouverts ne sont pas des spécifications.