Erreurs, bugs, questions - page 2356

 
fxsaber:

Que dit ce code ?

C'est la même chose.

 
Ilya Malev:

C'est la même chose.

comme MQL (en supposant qu'il soit converti en C++). Mais vous auriez pu le vérifier vous-même.
 
A100:
Cela et MQL (en supposant qu'il soit converti en C++). Mais vous auriez pu le vérifier vous-même.

Vérifié :


 
Ilya Malev:

Vérifié :

Je pense que vous vérifiez quelque chose de mal.

B*b1=a;

Une telle entrée dans MQL signifie la copie d'un objet a - vers un objet localisé par le pointeur b1. En général, bien sûr, elle ne devrait pas compiler.

Et pour ne pas confondre objets et pointeurs, il est préférable d'utiliser le préfixe p pour les pointeurs

 
Ilya Malev:

Vérifié :

S'il vous plaît, ne vous laissez pas piéger par ce comportement malencontreux.

Il y a deux problèmes ici ( ?):

  1. B *b1=a - une erreur explicite, le compilateur perçoit cette construction comme un appel de l'opérateur de copie A::A(const A &)

  2. Dans le premier cas, l'optimiseur a détecté que A::A(const A &) est vide, pas de membres - pas d'accès par "pointeur" (en fait, il n'y a pas de code pour appeler l'opérateur de copie, tout a été coupé).
    le virtuel B::f() n'est pas surchargé, donc au lieu d'un appel virtuel, c'était un simple appel, il n'y a pas d'adressage de membre dans B::f(), donc l'accès par "pointeur" a aussi été supprimé

    Dans le second cas, A::f() est une tentative d'appel virtuel, il y a un accès par "pointeur", mais pas d'objet a1, car une copie vide du constructeur A::A(const A &) a également été appelée pour A *a1=b
 
Ilyas:

S'il vous plaît, ne misez pas sur ce comportement malencontreux.

Il y a deux problèmes ici ( ?):

J'espère que vous allez corriger ce comportement erroné ? (faire une erreur de compilation) Parce qu'il est possible de faire une telle erreur par accident et que le compilateur ne réagit en aucune façon.

 
Alexey Navoykov:

J'espère que vous allez corriger ce comportement erroné ? Parce qu'il est possible de faire une telle erreur par accident et que le compilateur ne réagit en aucune façon.

Oui, nous allons le réparer.

La priorité est faible car seules les classes vides obtiennent du code fonctionnel.

 
Ilyas:

S'il vous plaît, ne misez pas sur ce comportement malencontreux.

Il y a deux problèmes ici ( ?):

  1. B *b1=a - une erreur évidente, le compilateur perçoit cette construction comme un appel à l'opérateur de copie A::A(const A &)

  2. Dans le premier cas, l'optimiseur a déterminé que A::A(const A &) est vide, pas de membres - pas d'accès par "pointeur" (en fait, il n'y a pas de code pour appeler l'opérateur de copie, tout a été coupé).
    le virtuel B::f() n'est pas surchargé, donc au lieu d'un appel virtuel, c'était un simple appel, B::f() n'a pas d'adressage de membre, donc l'accès par "pointeur" a également été supprimé.

    Dans le second cas, A::f() est une tentative d'appel virtuel, il y a un accès par "pointeur", mais pas d'objet a1, car une copie vide du constructeur A::A(const A &) a également été appelée pour A *a1=b

Merci pour la réponse détaillée, cependant, je suis un peu confus quant à la logique.

1) Pourquoi le compilateur voit-il la construction B* b1=a comme un appel de l'opérateur de copie A::A(const A&), (au lieu d'appeler B::B(const A&), parce que c'est la classe B à gauche de l'opérateur=)

2) Pourquoi le compilateur n'a-t-il pas généré l'avertissement "copy constructor missing" ?

3) pourquoi un appel de méthode "simple" est autorisé pour des objets inexistants (alors qu'une tentative d'appeler directement B::f() donne une erreur de compilation "not a static method call")

4) Et pourquoi le compilateur autorise-t-il un "simple" appel de méthode virtuelle ? À mon avis, la virtualité ne devrait pas dépendre de la présence ou de l'absence de données dans l'objet.

 
Ilya Malev:

1) Pourquoi le compilateur voit-il B* b1=a comme un appel à l'opérateur de copie A::A(const A&), (au lieu d'appeler B::B(const A&), parce que c'est la classe B à gauche de l'opérateur=)

C'est exactement ça. C'est un autre bug de MQL, que le compilateur permet librement des choses comme : B b = a ; C'est une violation des principes d'encapsulation. En C++, de telles choses ne se compilent pas naturellement, une conversion explicite est nécessaire. Et dans les anciennes versions de MQL, de telles choses ne pouvaient pas être faites aussi bien.

 
Ilya Malev:

Merci pour la réponse détaillée, cependant, je ne comprends pas bien la logique.

1) Pourquoi le compilateur perçoit-il la construction B* b1=a comme un appel à l'opérateur de copie A::A(const A&), (au lieu d'appeler B::B(const A&), parce que c'est la classe B à gauche de l'opérateur=)

2) Pourquoi le compilateur n'a-t-il pas généré l'avertissement "copy constructor missing" ?

3) pourquoi un appel de méthode "simple" est autorisé pour des objets inexistants (alors qu'une tentative d'appeler directement A::f() génère une erreur de compilation "not a static method call")

1) J'ai écrit que c'est une erreur évidente que nous corrigerons de toute façon.

2) le constructeur de copie est généré par le compilateur, s'il n'est pas déclaré par l'utilisateur.

3) la question n'est pas tout à fait claire.
Dans le contexte de la discussion :
On pourrait débattre longtemps de la question de savoir s'il faut ou non "déréférencer" un pointeur s'il n'y a pas d'accès à celui-ci ?
L'opération de déréférencement (obtenir le pointeur réel à partir du handle) est un code "interne" (non personnalisé) et coûteux (par rapport à son absence).
Pourquoi effectuer un déréférencement s'il n'y a pas d'accès au pointeur ?
Tant qu'il reste tel quel, l'opération de déréférencement est supprimée par l'optimiseur s'il n'y a pas d'accès au pointeur.