Auf Wiedersehen, Roboter - Hallo, Marasmus - Seite 8

 
simpleton:

Lokale Variablen und Parameter befinden sich im selben Geltungsbereich. Es spielt also keine Rolle, ob ein Parameter diesen Namen oder eine lokale Variable hat, aber in beiden Fällen verbirgt dieser Name den Namen im äußeren Geltungsbereich.

Nicht in jedem Fall. Bei der Übergabe einer Variablen per Referenz wird keine lokale Kopie erstellt, sondern direkt mit der übergebenen Variablen gearbeitet. Was für ein Versteckspiel findet hier also statt?
 
Andrei01:
Nicht in jeder Funktion. Wenn eine Variable per Referenz übergeben wird, wird keine lokale Kopie erstellt und die Operation wird direkt mit der übergebenen Variable durchgeführt. Was für ein Versteckspiel findet hier statt?

Hier findet das Verstecken von Namen statt. Alles andere - kopieren, nicht kopieren - ist zweitrangig. Wenn innerhalb einer Funktion ein Referenzname verwendet wird, wird die Arbeit an dem Objekt ausgeführt, auf das sich die Referenz bezieht. Wenn sie sich auf ein Objekt im äußeren Bereich bezieht, wird die Arbeit mit diesem Objekt ausgeführt. Dies liegt nicht daran, dass kein Name versteckt wird - das Verstecken ist vorhanden, genau wie in anderen Fällen - sondern daran, dass der Verweis auf dieses Objekt verweist. Eine Funktion wird auf diese Weise aufgerufen. Dieses Objekt wurde per Verweis weitergegeben und verweist nun auf es. Beim Aufruf und der Übergabe zum Zeitpunkt des Aufrufs eines anderen Objekts wird derselbe Funktionscode mit einem anderen Objekt funktionieren.

Ich habe ein Beispiel mit einem Typnamen und einem Variablennamen gegeben, d.h. mit Entitäten, die von ihrer Natur her so unterschiedlich wie möglich sind, um zu zeigen, dass sich das Verstecken auf Namen bezieht, und alles andere ist zweitrangig.

Als ich jedoch versuchte, ein weiteres Beispiel in MQL4++ zu diesem Thema zu erstellen, entdeckte ich zufällig, dass ein zusätzlicher Bereich für Parameter in MQL4++ erstellt wird. Der Geltungsbereich lokaler Variablen ist bereits darin verschachtelt:

#property strict

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

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

void OnStart() {
  f(3);
}

Dieses Beispiel ist KOMPLIZIERT mit einer charakteristischen Warnung:

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

Und später wird sie erfolgreich ausgeführt:

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

Es ist offensichtlich, dass in MQL4++ ein weiterer "Layer"-Bereich für Parameter geschaffen wird. Aus diesem Grund ist es möglich, eine lokale Variable mit demselben Namen wie der Parameter zu deklarieren.

In C/C++ gibt es keine solche "Schicht":

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

Der Compiler erklärt im Volksmund, dass es bereits eine Variable mit diesem Namen im Geltungsbereich gibt:

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

Das heißt, der Geltungsbereich von Funktionsparametern und ihren lokalen Variablen ist ein und derselbe.

Warum das in MQL4++ nicht der Fall ist und zu welchem Zweck - das ist natürlich eine interessante Frage...

 
simpleton:

void f(int a)

Dieses Beispiel KOMPILIERT mit einer charakteristischen Warnung:

In diesem Fall geht es um die Übergabe einer Variablen per Referenz und eine fehlerhafte Warnung, nicht um die Erstellung einer lokalen Kopie.

void f(int& a)
 

Ich habe nur die ersten paar Beiträge gelesen.

Natürlich geht es auch unter der Matte nicht ganz glatt. Hier gibt es einige Versäumnisse der Entwickler beim Testen des Produkts, das den Endverbraucher erreicht. Allerdings ist auch MT4 nicht stark in Multi-Währungs-Strategien (Testen), und muss, muss verfeinert werden. Ich hoffe also, dass es eines Tages doch noch so weit sein wird.

Wenn Sie noch nicht gut programmieren können, sollten Sie die Demoversion vorerst verwenden. Wie immer kommt ein schlechter Tänzer den "Bällen" in die Quere, einschließlich Gold und Rosa.

Viel Glück!


 
Andrei01:

Dies ist ein Fall der Übergabe einer Variablen per Referenz und einer fehlerhaften Warnung, nicht der Erstellung einer lokalen Kopie.

void f(int& a)

Für die Art der Warnung spielt das keine Rolle. Außerdem spielt es keine Rolle, ob eine Variable als Referenz oder als Wert übergeben wird, sondern welcher Typ sie ist:

#property strict

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

Der Code wird kompiliert, und die von Ihnen angesprochene Warnung wird erzeugt:

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

Aus irgendeinem Grund wollen Sie das nicht verstehen.

Die Warnung selbst ist keineswegs fehlerhaft. Darüber hinaus ist die Umfangsverfolgung in MQL4++ auf den ersten Blick erstaunlich gut, wenn man sie mit der Art und Weise vergleicht, wie andere Dinge gemacht werden.

Warnungen sind zwar richtig, aber unpraktisch, und doch kann man sie nicht abstellen - darum geht es ja. Und schon gar nicht die Übertragung des Links.

 
simpleton:

Für die Art der Warnung ist dies unerheblich. Außerdem spielt es keine Rolle, ob die Variable als Referenz oder als Wert übergeben wird

Es besteht ein großer Unterschied im Wesen der Warnung zwischen der Übergabe der Variablen selbst und ihrer Änderung in einer Funktion und der Erstellung einer Kopie der Variablen, während die Variable selbst unverändert bleibt.

Und die Tatsache, dass die Warnungen nicht deaktiviert oder angepasst werden können, ist es eine klassische MC proprietären Stil - "nicht lassen":))) Man kann nichts dagegen tun, aber man kann es nur demütig und sanftmütig akzeptieren, weil dieser Stil zu einem religiösen Attribut erhoben wurde... Es hat keinen Sinn, hier nach Logik oder irgendeiner Art von Gerechtigkeit zu suchen. ))

 

Igitt igitt, bei mir läuft das ganze Methaquot-Zeug wie am Schnürchen.

Überhaupt keine Beschwerden.

 
simpleton:

Ein potenzieller Fehler ist genau das: ein potenzieller Fehler ist nicht unbedingt ein Fehler. Daher ist die Aussage "das bedeutet, dass wir diese Fehler beheben müssen" falsch, da es sich möglicherweise gar nicht um Fehler handelt.

...

Diese Leute sind Freaks. Solche Idioten kämpfen gegen den Compiler wie gegen eine Windmühle und verstehen nicht, worauf es ankommt: Der Compiler ist Ihr Verbündeter! Freuen Sie sich, wenn der Compiler auf potenziell unsichere Codefragmente schimpft. Freuen Sie sich, auch wenn die Anwendung gleich nach dem Start mit einer Fehlermeldung abstürzt. Aber Gott bewahre, dass Sie einen unüberschaubaren Code erhalten, wenn es keine Fehler oder Warnungen gibt und das Programm gut zu funktionieren scheint, aber von Zeit zu Zeit seltsame Störungen auftreten, deren Ursache nirgends zu finden ist. In solchen Momenten wird man mit Dampf überschüttet und träumt von Fehlern wie"ungültiger Zeiger" oder "Division durch Null".
 
C-4:
Aber Gott bewahre, dass Sie einen unüberschaubaren Code bekommen, wenn es keine Fehler oder Warnungen gibt und das Programm gut zu funktionieren scheint, aber hin und wieder seltsame Fehler auftreten, deren Grund nirgends zu finden ist. In solchen Momenten wird man mit Dampf überschüttet und träumt von Fehlern wie "ungültiger Zeiger" oder "Division durch Null".

Der Compiler hat nichts damit zu tun, es ist typisch für fehlerhaftes Schreiben, wenn es keine Testprüfungen in gefährlichen Codefragmenten gibt, in denen undefinierte oder fehlerhafte Zustände möglich sind, weshalb die Störungen auftreten.

Funktionale Codeprüfungen haben nichts mit dem Compiler zu tun, und es macht keinen Sinn, dies von vornherein zu erwarten.

Auch hier gilt, dass professionelle Programmierer in der Regel nicht auf die Warnungen achten, weil sie die Logik des Compilers kennen, während Compiler bei der Überprüfung der Codefunktionalität nutzlos sind.

 
Andrei01:

Es besteht ein großer Unterschied in den wesentlichen Warnungen zwischen der Übergabe der Variablen selbst und ihrer Änderung in einer Funktion und der Erstellung einer Kopie davon, wobei die Variable selbst unverändert bleibt.

Hier handelt es sich nur um eine andere Art von Warnung. Über das Verstecken von Namen.

Die Variable selbst wird nicht übergeben. Eine Referenz darauf wird übergeben.