Au revoir le robot - bonjour le marasme - page 8

 
simpleton:

Les variables locales et les paramètres sont dans la même portée, donc - il n'est pas important si un paramètre a ce nom ou une variable locale, mais de toute façon ce nom cache le nom dans la portée externe.

Pas dans tous les cas. Lorsqu'une variable est passée par référence, aucune copie locale n'est créée et le travail est effectué directement sur la variable passée. Alors quelle sorte de dissimulation se passe ici ?
 
Andrei01:
Pas dans n'importe quelle fonction. Lorsqu'une variable est passée par référence, une copie locale n'est pas créée et l'opération est effectuée directement avec la variable passée. Alors quelle sorte de dissimulation se passe ici ?

C'est ici que la dissimulation des noms a lieu. Tout le reste - la copie, pas la copie - est secondaire. Dans une fonction, lorsqu'un nom de référence est utilisé, le travail sera effectué sur l'objet auquel la référence fait référence. S'il fait référence à un objet dans la portée externe, le travail sera effectué avec cet objet. Ce n'est pas parce qu'il n'y a pas de dissimulation de nom - la dissimulation est présente, comme dans les autres cas - mais parce que la référence pointe vers cet objet. Une fonction est appelée de cette façon. J'ai transmis cet objet par référence et il pointe maintenant vers lui. Lors de l'appel et du passage au moment de l'appel d'un autre objet, le même code de fonction fonctionnera avec un autre objet.

Je donnais un exemple avec un nom de type et un nom de variable, c'est-à-dire avec des entités de nature aussi différente que possible, pour montrer que le masquage s'applique/référence aux noms, et que tout le reste est secondaire.

Cependant, en essayant de créer un autre exemple dans MQL4++ sur ce thème, j'ai découvert par hasard qu'une portée supplémentaire est créée pour les paramètres dans MQL4++. La portée des variables locales y est déjà imbriquée :

#property strict

void f(int a) {
  int saved = a;
  int a = a + 1;

  Print("saved = " , saved, ", a = ", a);
}

void OnStart() {
  f(3);
}

Cet exemple est COMPILÉ avec un avertissement caractéristique :

declaration of 'a' hides local declaration at line 3    3.mq4   5       7

Et plus tard, il est exécuté avec succès :

23:52:22 Script 3 EURUSDm,H1: loaded successfully
23:52:22 3 EURUSDm,H1: initialized
23:52:22 3 EURUSDm,H1: saved = 3, a = 4
23:52:22 3 EURUSDm,H1: uninit reason 0
23:52:22 Script 3 EURUSDm,H1: removed

Il est évident qu'une autre "couche" de portée est créée pour les paramètres dans MQL4++. C'est pourquoi il est possible de déclarer une variable locale portant le même nom que le paramètre.

En C/C++, il n'y a pas de telle "couche" :

void f(int a) {
  int saved = a;
  int a = a + 1;
}

Le compilateur explique populairement qu'il existe déjà une variable avec ce nom dans la portée :

$ icpc -c 1.cpp
1.cpp(3): error: "a" has already been declared in the current scope
    int a = a + 1;
        ^

C'est-à-dire que la portée des paramètres de la fonction et de ses variables locales est la même.

Pourquoi ce n'est pas le cas dans MQL4++ et dans quel but, c'est bien sûr une question intéressante...

 
simpleton:

void f(int a)

Cet exemple COMPILE avec un avertissement caractéristique :

Ce cas traite du passage d'une variable par référence et d'un avertissement erroné, et non de la création d'une copie locale.

void f(int& a)
 

Je n'ai lu que les premiers messages.

Bien sûr, les choses ne vont pas non plus très bien sous le tapis. Les développeurs ne testent pas toujours le produit qui parvient à l'utilisateur final. Cependant, MT4 n'est pas non plus très fort en matière de stratégies multi-devises (tests), et a besoin, doit être affiné. J'espère donc que ce sera le cas un jour, après tout.

Si vous n'êtes pas doué pour la programmation, ne passez pas à la vraie, et utilisez la démo pour l'instant. Comme toujours, un mauvais danseur se met en travers du chemin des "boules", y compris l'or et le rose.

Bonne chance !


 
Andrei01:

Il s'agit d'un cas de passage d'une variable par référence et d'un avertissement erroné, et non de la création d'une copie locale.

void f(int& a)

Cela n'a pas vraiment d'importance en termes de nature de l'avertissement. De plus, il importe peu qu'une variable soit transmise par référence ou par valeur, mais aussi de quel type elle est :

#property strict

int a; // line 3
class A { };
void f(A *&a) { } // line 5
void OnStart() { }

Le code se compile, l'avertissement dont vous parlez est généré :

declaration of 'a' hides global declaration at line 3   3.mq4   5       12

Pour une raison quelconque, tu ne veux pas comprendre ça.

L'avertissement lui-même n'est pas du tout défectueux. De plus, à première vue, le suivi de la portée dans MQL4++ est étonnamment bien fait par rapport à la façon dont d'autres choses sont faites.

Les avertissements, s'ils sont vrais, ne sont pas pratiques, et pourtant vous ne pouvez pas les désactiver - c'est là tout l'intérêt. Et en aucun cas la transmission du lien.

 
simpleton:

En ce qui concerne la nature de l'avertissement, cela n'est pas pertinent. En outre, il importe peu que la variable soit passée par référence ou par valeur.

Il y a une grande différence dans l'essence de l'avertissement entre passer la variable elle-même et la modifier dans une fonction et créer une copie de celle-ci, alors que la variable elle-même reste inchangée.

Et le fait que les avertissements ne puissent pas être désactivés ou personnalisés, c'est un style propriétaire classique de MC - " ne pas laisser " :))) Vous ne pouvez rien y faire, mais vous ne pouvez que l'accepter humblement et docilement, car ce style a été élevé au rang d'attribut religieux... Il est inutile de chercher une logique ou une quelconque justice ici. ))

 

Ugh ugh j'ai tous les trucs de methaquot qui fonctionnent comme une horloge.

Pas de plaintes du tout.

 
simpleton:

Une erreur potentielle n'est que cela, une erreur potentielle n'est pas nécessairement une erreur. Par conséquent, l'affirmation selon laquelle "cela signifie que nous devons corriger ces erreurs" est fausse, car il se peut que ce ne soit PAS du tout des erreurs.

...

Ces gens sont des geeks. De tels abrutis combattent le compilateur comme un moulin à vent sans comprendre l'essentiel : le compilateur est votre allié! Réjouissez-vous lorsque le compilateur jure sur des fragments de code potentiellement dangereux. Réjouissez-vous même si l'application se bloque dès son lancement avec une chaîne d'erreurs. Mais que Dieu vous garde d'obtenir un code ingérable lorsqu'il n'y a pas d'erreurs ou d'avertissements et que le programme semble bien fonctionner mais que d'étranges problèmes surviennent de temps en temps, dont la cause ne peut être trouvée nulle part. Dans ces moments-là, on se couvre de vapeur et on se met à rêver d'erreurs comme"pointeur invalide" ou "division par zéro".
 
C-4:
Mais que Dieu vous garde d'obtenir un code ingérable lorsqu'il n'y a pas d'erreurs ou d'avertissements et que le programme semble bien fonctionner mais que des bogues étranges surviennent de temps à autre, dont la raison ne peut être trouvée nulle part. Dans ces moments-là, on se couvre de vapeur et on se met à rêver d'erreurs comme "pointeur invalide" ou "division par zéro".

Le compilateur n'a rien à voir avec cela, il s'agit d'une écriture boguée typique lorsqu'il n'y a pas de contrôles de test dans des fragments de code dangereux où des états indéfinis ou erronés sont possibles, c'est pourquoi les pépins apparaissent.

Les contrôles de code fonctionnel n'ont rien à voir avec le compilateur et il est inutile de s'y attendre dès le départ.

Encore une fois, les programmeurs professionnels ne regardent généralement pas les avertissements car ils connaissent la logique du compilateur alors que les compilateurs sont inutiles pour vérifier la fonctionnalité du code.

 
Andrei01:

Il y a une grande différence dans les avertissements d'essence entre passer la variable elle-même et la modifier dans une fonction et en faire une copie, alors que la variable elle-même reste inchangée.

Ici, c'est juste un autre type d'avertissement. A propos de la dissimulation des noms.

La variable elle-même n'est pas transmise. Une référence à celui-ci est passée.

Raison: