Les deux (a)
et (b)
suite à un comportement indéfini. C'est toujours un comportement indéfini d'appeler une fonction membre par l'intermédiaire d'un pointeur null. Si la fonction est statique, c'est techniquement pas défini en tant que bien, mais il y a du litige.
La première chose est de comprendre pourquoi c'est un comportement indéfini déréférencer un pointeur null. En C++03, il y a effectivement un peu d'ambiguïté ici.
Bien que le "déréférencement d'un pointeur null résultats dans un comportement indéfini" est mentionné dans les notes dans les deux §1.9/4 et §8.3.2/4, il n'est jamais explicitement mentionnée. (Les Notes sont non-normatif.)
Cependant, on peut essayer de déduire à partir de §3.10/2:
Une lvalue se réfère à un objet ou une fonction.
Lors de la déférence, le résultat est une lvalue. Un pointeur null ne fait pas référence à un objet, par conséquent, lorsque nous utilisons la lvalue nous avoir un comportement indéfini. Le problème est que la phrase précédente, il n'est jamais dit, alors, que signifie "utiliser" la lvalue? Tout de même générer, à tous, ou à utiliser dans le cadre plus formel sentiment d'effectuer des lvalue-à-rvalue de conversion?
De même, il ne peut absolument pas être convertie en une rvalue (§4.1/1):
Si l'objet pour lequel la lvalue se réfère n'est pas un objet de type T et n'est pas un objet d'un type dérivé de T, ou si l'objet est non initialisée, un programme qui nécessite cette conversion a un comportement indéfini.
Ici, il est certainement un comportement indéfini.
L'ambiguïté vient de si oui ou non c'est un comportement indéfini de déférence , mais pas utiliser la valeur d'un pointeur non valide (c'est, obtenir une lvalue, mais pas de le convertir à une rvalue). Si non, alors int *i = 0; *i; &(*i);
est bien définie. C'est un actif en question.
Nous avons donc une stricte "déréférencer un pointeur null, obtenir un comportement indéfini" de la vue et de la faiblesse de l'utilisation d'un déréférencé pointeur null, obtenir un comportement indéfini".
Maintenant nous pencher sur la question.
Oui, (a)
résultats dans un comportement indéfini. En fait, si l' this
est nul, quel que soit le contenu de la fonction , le résultat est indéfini.
Cela résulte du §5.2.5/3:
Si E1
a le type "pointeur vers la classe X", alors l'expression E1->E2
est convertie en une forme équivalente (*(E1)).E2;
*(E1)
entraînera un comportement indéfini avec une interprétation stricte, et .E2
le convertit en une rvalue, faisant d'elle un comportement indéfini de la faiblesse de l'interprétation.
Il en résulte également que c'est un comportement indéfini directement à partir de (§9.3.1/1):
Si une fonction membre non statique d'une classe de X est appelée pour un objet qui n'est pas de type X, ou d'un type dérivé de X, le comportement est indéfini.
Avec des fonctions statiques, la stricte contre la faiblesse de l'interprétation qui fait la différence. Strictement parlant, il n'est pas défini:
Un membre statique peut être appelée à l'aide de la classe membre de la syntaxe d'accès, auquel cas l'objet-l'expression est évaluée.
C'est, il est évalué comme si c'étaient des non-statique, et nous avons encore une fois de déréférencer un pointeur null avec (*(E1)).E2
.
Cependant, parce qu' E1
n'est pas utilisé dans un membre statique-appel de la fonction, si nous utilisons la faiblesse de l'interprétation que l'appel est bien définie. *(E1)
résultats dans une lvalue, la fonction statique est résolu, *(E1)
est éliminé, et la fonction est appelée. Il n'y a pas de lvalue-à-rvalue de conversion, donc il n'y a pas de comportement indéfini.
Dans C++0x, comme de n3126, l'ambiguïté demeure. Pour l'instant, d'être en sécurité: utilisation de l'interprétation stricte.