Fehler, Irrtümer, Fragen - Seite 2725

 
Vict:

Glauben Sie, dass Ihr Sharp auf einem sauberen Feld erschienen ist? Die in C verwurzelte Struktur ist ein stummer Container, der keinen zusätzlichen Zucker enthält.

Nun, der Mensch hat sich aus einem Affen entwickelt. Aber das bedeutet nicht, dass der Mensch ein dummer Affe "ohne zusätzlichen Zucker" ist, oder? ) Ich habe bereits erklärt, dass in der Tat MQL-Strukturen = C#-Strukturen, mit einem kleinen Unterschied: in C# können sie noch Schnittstellen implementieren. Schnittstellen, Carl! )

Wie können Sie so sicher sein? Aufruf einer Funktion aus einer anderen Übersetzungseinheit/einem anderen Modul/Zyklen/Compiler außer Takt/... . Überschätzen Sie nicht die Fähigkeiten des Optimierers. Es handelt sich dabei nicht um eine Copy-Elision-Optimierung, zu der die Compiler verpflichtet sind. Wenn die Optimierer so schlau werden und es nichts mehr kostet, werden sie in den nächsten C-Standard schreiben: "Standardinitialisierung lässt ein Objekt nicht in einem undefinierten Zustand".

Weil es die trivialste und primitivste Sache ist, die man nicht einmal als Optimierung bezeichnen kann. Ich glaube, alle Compiler machen es standardmäßig, sogar im Debug-Modus. Was kann einfacher sein? Während des Code-Parsens muss man den Zugriff auf Variablen verfolgen. Wenn es einen wiederholten Schreibvorgang gibt und kein Lesevorgang stattgefunden hat, dann wird der vorherige Eintrag ausgeschnitten.

Sie können es ignorieren, aber dann müssen Sie sich nicht wundern, dass anständige Programmierer Sie für einen Scheiß-Coder halten, wenn sie Ihre mit Funktionen vollgestopften Strukturen sehen

Ich würde Ihre Herangehensweise an uninitialisierte Operationen eher als "shit-coding" bezeichnen. Was ist die wichtigste Eigenschaft, die ein Computerprogramm besitzen muss? Stabilität. Bei gleichen Eingabedaten muss es unveränderliche Ergebnisse liefern. Und Sie schlagen vor, das zu vergessen. Irgendwo haben Sie vergessen, eine Variable zu initialisieren, irgendwo haben Sie ein neues Feld in die Struktur eingefügt und es wurde im gesamten Programm uninitialisiert und das Programm implodierte. Das Programm funktioniert so und so...

Die Sprache C wurde in einer weit zurückliegenden Zeit entwickelt, als die Hardware noch nicht sehr leistungsfähig war, so dass ein Großteil der Optimierungsarbeit dem Programmierer überlassen wurde. Wenn es Sie so sehr juckt, warum verweisen Sie dann auf C und nicht z.B. auf Assembler? Kodieren Sie die Handelssysteme in Assembler. Ich bin sicher, sie werden die schnellsten sein, vielleicht sogar dem Markt voraus)

 
Alexey Navoykov:

Weil es die trivialste und primitivste Sache ist, die man kaum als Optimierung bezeichnen kann. Ich denke, alle Compiler tun es standardmäßig, sogar im Debug-Modus. Was könnte einfacher sein? Während des Parsens des Codes den Zugriff auf Variablen überwachen. Wenn es einen wiederholten Schreibvorgang gibt und kein Lesevorgang stattgefunden hat, dann wird der vorherige Eintrag ausgeschnitten.

Wenn das Programm zur Kompilierzeit vollständig vorhersehbar wäre, müsste es zur Laufzeit gar nicht ausgeführt werden. Es sollte per Definition etwas von der Außenwelt aufnehmen und ein darauf basierendes Ergebnis ausgeben, und das ist die Unsicherheit, die dem Optimierer im Weg steht. Ein weiteres Geheimnis - gemeinsam genutzte Bibliotheken werden zur Laufzeit mit der Anwendung verknüpft, der Optimierer kann dort nichts nachverfolgen. Es gibt noch eine Million weiterer Fälle, die verworfen werden müssen. (Eine Million, Karl!)

Irgendwo habe ich vergessen, eine Variable zu initialisieren oder ein neues Feld zu einer Struktur hinzugefügt, die im gesamten Programm nicht initialisiert wurde, und das Programm läuft weiter. Das Programm funktioniert so und so...

Irgendwo habe ich mit 2 statt mit 3 multipliziert, fn() statt fn_() aufgerufen, ... . Wenn Sie die falschen Hände haben, sind Sie in Schwierigkeiten.

Die Sprache C wurde vor langer Zeit entwickelt, als die Möglichkeiten der Hardware noch sehr gering waren, weshalb ein Großteil der Optimierungsarbeit dem Programmierer überlassen wurde. Wenn es Sie so sehr juckt, warum verweisen Sie dann auf C und nicht auf Assembler? Kodieren Sie die Handelssysteme in Assembler. Ich bin sicher, sie werden die schnellsten sein, vielleicht sogar vor dem Markt.

zu Ihrer Information: C-Standards (die neuesten, es sind keine C++-Standards): C11, C18, C2x ist in Vorbereitung. Vielmehr haben Sie dies aus Inkompetenz geschrieben.
 
Vict:

Wäre das Programm zur Kompilierzeit vollständig vorhersehbar, bräuchte es zur Laufzeit gar nicht ausgeführt zu werden. Definitionsgemäß muss er etwas aus der Außenwelt aufnehmen und darauf basierend ein Ergebnis ausgeben, und das ist eine Unsicherheit, die den Optimierer behindert. Ein weiteres Geheimnis - gemeinsam genutzte Bibliotheken werden zur Laufzeit mit der Anwendung verknüpft, der Optimierer kann dort nichts nachverfolgen. Es gibt noch eine Million weiterer Fälle, die verworfen werden müssen. Eine Million, Karl!)

DerDatenaustausch mit der Außenwelt ist ein Spezialfall und erfordert spezielle Lösungen. Wir sprechen von der Programmierung als solcher und den Fällen, in denen der Compiler garantiert weiß, dass die Variable nicht von außen gesteuert wird. Und das dürfte die überwiegende Mehrheit der Fälle sein. Andernfalls haben Sie eine reine Systemprogrammierung, die wirklich besser in C oder noch besser - in Assembler zu machen ist.

Irgendwo mit 2 statt mit 3 multipliziert, fn() statt fn_() aufgerufen, . . Wenn deine Hände krumm sind, gibt es Ärger.

Wenn Sie mit 2 statt mit 3 multiplizieren, erhalten Sie einen stabilen Fehler im Programm, der leicht zu diagnostizieren und zu finden ist. Und wenn die Variable nicht initialisiert ist, erhalten Sie etwas, das mal funktioniert und mal nicht, mit unvorhersehbaren Folgen. Im Allgemeinen ist es etwas seltsam, dass ich Ihnen als erfahrener Programmierer solche Grundlagen erkläre.

 
Alexey Navoykov:

Datenaustausch mit der Außenwelt - das sind Sonderfälle, die besondere Lösungen erfordern. Aber wir sprechen hier von der Programmierung als solcher, und zwar in den Fällen, in denen der Compiler garantiert weiß, dass die Variable nicht von außen gesteuert wird. Und das sollte die überwiegende Mehrheit der Fälle sein. Andernfalls erhält man eine reine Systemprogrammierung, die man besser in C oder noch besser - in Assembler macht.

Die Kommunikation mit der Außenwelt ist ein wesentlicher Bestandteil eines jeden Programms. Lassen Sie mich wiederholen - andernfalls kann es in der Kompilierzeit herausgefunden werden. Wird der Compiler zum Beispiel die Initialisierung an dieser Stelle kürzen?

int i = 54;
if (read_socket() == SIGNAL) {
   fn(i);
}
i = 100;
...

// естественно, что никто не пишет такой бред:
int q = 3;
q = 7;
q = 9;
fq(q);

Offensichtlich hat sie keine Ahnung, was read_socket() zurückgeben wird. Das gesamte Programm ist von der Interaktion mit der Außenwelt "durchdrungen". + hier einen Aufruf an externe Module hinzufügen... .

Wenn man sie mit 2 statt mit 3 multipliziert, erhält man einen stabilen Fehler im Programm, der leicht zu diagnostizieren und zu finden ist. Und mit einer nicht initialisierten Variablen erhält man etwas, das mal funktioniert und mal nicht, von Zeit zu Zeit, mit unvorhersehbaren Folgen. Eigentlich ist es seltsam, dass ich Ihnen, der sich als erfahrener Programmierer ausgibt, solche Grundlagen erkläre.

Wenn Sie einen stabilen Fehler erhalten wollen, ist es sehr einfach, den Stack zu initialisieren:

int main() {
    if (true)
        int init_stack[10000] {0};
}

Auch die Initialisierung des Speichers von HIP aus ist ein Kinderspiel. Wenn wir in eine Darstellungsfalle laufen, werden wir überhaupt einen Kerndump bekommen.

Noch einmal, wenn Optimierer sehr klug wären, würden sie Standard-Init mit Wert-Init gleichsetzen, mit Einfügen von Initialisierungsanweisungen durch den Compiler, wie es noch in einigen C11 benötigt wird, aber leider. Niemand zwingt Sie, wenn Sie nicht wollen, T val{} zu machen; Ich bin es leid, elementare Dinge zu erklären.

 
Vict:

Noch einmal, wenn Optimierer sehr schlau wären, würden sie Standard-Init mit Wert-Init gleichsetzen, wobei der Compiler bei Bedarf Initialisierungsanweisungen in einige C11 einfügt, aber leider. Niemand zwingt Sie, wenn Sie nicht wollen, T val{} zu machen; Ich bin es leid, elementare Dinge zu erklären.

Denn, so wie ich es verstehe, beschreibt der C++ Standard die Regeln sehr formal, ohne Kontextualisierung, d.h. Initialisierung entweder immer oder nie. Zum Vergleich, in C# kann man eine Variable ohne Initialisierung deklarieren, aber weiter im Code muss sie unbedingt initialisiert werden. Das heißt, der Compiler analysiert den nachfolgenden Code und nicht nur den aktuellen Befehl. Dies ist in den Sprachregeln festgelegt. Der Standard sieht jedoch keine Analyse in C++ vor. Wenn sie also die Initialisierung erzwingen, werden Sie sich beschweren, dass ich alles selbst kontrollieren und initialisieren will! )

 
Alexey Navoykov:

Weil der C++-Standard, so wie ich ihn verstehe, die Regeln sehr formal und ohne Kontextualisierung beschreibt, d.h. man initialisiert entweder immer oder nie. Im Vergleich dazu kann man in C# eine Variable ohne Initialisierung deklarieren, aber weiter im Code muss sie unbedingt initialisiert werden. Das heißt, der Compiler analysiert den nachfolgenden Code und nicht nur den aktuellen Befehl. Dies ist in den Sprachregeln festgelegt. Der Standard sieht jedoch keine Analyse in C++ vor. Wenn sie also die Initialisierung erzwingen, werden Sie sich beschweren, dass ich alles selbst kontrollieren und initialisieren will! )

Es ist nur so, dass bewährte Lösungen zum Ziel führen, und wenn sie sofort funktionieren und oft unnötigen Aufwand verursachen, wird sie niemand einbeziehen. Zum Beispiel haben sie in der Norm ein MUSS für den Compiler vorgeschrieben, um copy elision in c++17 zu machen.

 

Das Thema heißt "Bugs, Bugs, Fragen".

Bitte erstellen Sie ein Thema, in dem Sie MQL gegen C#, C++ und andere Dinge im Zusammenhang mit Syntax, Compilern und mentalem Training diskutieren.

Sie verschmutzen den Thread, und andere Fragen und Nachrichten von Benutzern gehen in Ihrer Diskussion unter.

Sie fragen mich, wo ich eine Frage stellen soll - ich werde hierher verwiesen, und die Antwort lautet: "Die Onkels streiten sich dort hundert Seiten lang, also werde ich mich nicht einmischen, der Rest ist bedeutungslos ...

 
const int DEFAULT_INT_VALUE   = 147;
input int thisIsAnInput       = DEFAULT_INT_VALUE;
NoConstForInput.mq5' NoConstForInput.mq5 1 1
DEFAULT_INT_VALUE' - Konstante erwartet NoConstForInput.mq5 13 33
1 Fehler, 0 Warnungen 2 1

Gebäude 2361 und 2390

 
Alain Verleyen:
NoConstForInput.mq5' NoConstForInput.mq5 1 1
DEFAULT_INT_VALUE' - Konstante erwartet NoConstForInput.mq5 13 33
1 Fehler, 0 Warnungen 2 1

Gebäude 2361 und 2390

#define  DEFAULT_INT_VALUE 147
 
Vict:

Wenn Sie einen stabilen Fehler erhalten wollen, ist die Initialisierung des Stacks sehr einfach:

Auch die Initialisierung des Speichers aus einem HIP ist ein Kinderspiel. Wenn wir in eine Darstellungsfalle laufen, erhalten wir einen Kernspeicherauszug.

Eine letzte Bemerkung: Bitte seien Sie nicht böse auf die Moderatoren )).

Ich muss klären, warum der Stack von Aufruf zu Aufruf unterschiedliche Werte aufweist. Es geht nur darum, https://ru.wikipedia.org/wiki/ASLR zu schützen , und wie ich bereits sagte, muss man nicht einmal irgendetwas analysieren. In meinem Fall führe ich die Software unter gdb (Debugger) aus, wodurch sie bei jedem Durchlauf an der gleichen Adresse platziert wird, d.h. der Stack wird nicht durch "zufällige" Rücksprungadressen verunreinigt.