Erreurs, bugs, questions - page 2045

 

J'ai découvert la cause de la divergence. Avec OPTIMIZE=0, il y a une erreur, mais pas avec OPTIMIZE=1. Je n'utilise généralement que OPTIMIZE=0

 
fxsaber:

Si je trouve une explication logique (non contradictoire) pour le résultat, je ne vois pas le bug. Je ne pense pas qu'il soit acceptable de prouver un bug si le résultat ne correspond pas à C++. C'est en C++ que quelqu'un a pensé de cette façon et l'a fait. Mais ils ne l'ont peut-être pas pensé et ne l'ont donc pas fait. C'est pourquoi il est préférable de ne pas se référer à quelque chose d'extérieur, mais de se fier à son propre concept intérieur de ce qui doit être. Et il est souhaitable que ce "propre" soit vraiment le sien. Ce n'est pas le résultat de l'imposition imperceptible de stéréotypes "comme il faut" au fur et à mesure que l'on acquiert de l'expérience en programmation.

Si vous n'avez pas votre propre explication, cela signifie qu'il n'y a pas d'erreur. Et si cette explication apparaît un an plus tard et est plutôt convaincante, tout le monde devra-t-il tout refaire ? Dans le C++, ils ont déjà réfléchi cent fois à la raison pour laquelle il faut faire comme ça et pas comme ça. Et l'explication est nécessaire si quelque chose est configuré différemment dans MQL et dans C++ et non vice versa.

 
Alexey Viktorov:
Une variable statique peut être initialisée avec une constante ou une expression constante correspondant à son type , contrairement à une simple variable locale, qui peut être initialisée avec n'importe quelle expression.


Mais pas une fonction.

Les instances de classes statiques devraient alors être interdites, car elles sont initialisées par une fonction de construction.

 

Et voici d'autres informations sur l'initialisation des variables. Si vous suivez ce qui est indiqué dans la documentation, vous ne pouvez pas non plus faire référence à d'autres variables globales/statiques. Comme il ne s'agit pas d'une expression constante :

int a= 1;
int b= a+1;  // Согласно документации, такая инициализация не возможна

void OnStart()
{
  Print(b);
}

Cependant, pour l'instant, cela fonctionne. Et je suppose que de nombreuses personnes ont toujours utilisé de telles constructions sans s'en rendre compte. Mais il s'avère que les développeurs peuvent le désactiver à tout moment. Et, comme dans le cas de l'initialisation des fonctions, ces codes seront toujours compilés avec succès, mais ils ne fonctionneront pas correctement. Dans l'ensemble, le MQL est une bombe à retardement.

 
Alexey Navoykov:

Et voici une autre chose concernant l'initialisation des variables. Si vous suivez ce qui est indiqué dans la documentation, vous ne pouvez pas non plus faire référence à d'autres variables globales/statiques. Parce que ce n'est pas une expression constante :

//+------------------------------------------------------------------+
//|                                                   ExpertMACD.mq5 |
//|                   Copyright 2009-2017, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
CExpert ExtExpert;

est initialisée par une fonction constructeur - à proscrire !

C'est si vous résumez logiquement les derniers messages

Alexey Navoykov:

J'ai trouvé la raison de cette différence. Avec OPTIMIZE=0, il y a une erreur, mais pas avec OPTIMIZE=1. J'utilise toujours uniquement OPTIMIZE=0.

Dans le terminal 32 bits, une erreur se produit à n'importe quel OPTIMIZE

int g1( int& t[] ) { return ArraySize( t ); }
int g2( int& t[] ) { return g1( t ); }
void OnStart()
{
        int t[] = { 1, 2, 3, 4, 5 }; //всего 5
        Print( g2(t)); //Результат:          3
}
 
A100:

est initialisée par une fonction constructeur - à proscrire !

C'est si vous résumez logiquement les derniers messages

Eh bien, la personne s'est exprimée de manière incorrecte. Bien entendu, nous parlons d'une valeur d'initialisation, et non d'une fonction d'initialisation.


Et que diable - les interdictions. Ils ne causent pas de problèmes par eux-mêmes. Mais lorsque cette interdiction n'est pas contrôlée par le compilateur de quelque manière que ce soit, mais génère un algorithme qui contourne les règles du langage, elle ne convient pas du tout. Maintenant, vous devrez fouiller dans tout le code à la recherche de telles choses et être constamment sur vos gardes. Eh bien, au diable ce genre de programmation, je préfère rester sur l'ancienne version.

 
Alexey Navoykov:
Je vois, je m'excuse alors, je n'ai pas remarqué tout de suite. Je suis surpris, bien sûr, de voir comment ils ont réussi à le changer discrètement et à ne rien dire à personne. Ce que je ne comprends pas, c'est pourquoi le compilateur ne réagit pas à l'exécution d'une opération invalide. C'est-à-dire que le bogue est présent dans tous les cas.
Pourquoi pensez-vous que c'est invalide ? Veuillez l'utiliser à votre propre discrétion. Le problème est que lorsqu'une variable statique est initialisée par une fonction, l'initialisation est "mise en pause" et la fonction est exécutée. Et dans l'exemple ci-dessus, il y a toujours une variable statique dans cette fonction qui n'a pas encore été initialisée. Ainsi, une variable initialisée par une fonction prend une valeur différente.
 
Alexey Navoykov:

Et voici d'autres informations sur l'initialisation des variables. Si vous suivez ce qui est indiqué dans la documentation, vous ne pouvez pas non plus faire référence à d'autres variables globales/statiques. Comme il ne s'agit pas d'une expression constante :

Cependant, pour l'instant, cela fonctionne. Et je suppose que de nombreuses personnes ont toujours utilisé de telles constructions sans s'en rendre compte. Mais il s'avère que les développeurs peuvent le désactiver à tout moment. Et, comme dans le cas de l'initialisation des fonctions, ces codes seront toujours compilés avec succès, mais ils ne fonctionneront pas correctement. En somme, l'ensemble du code MQL est une mine qui travaille au ralenti.

Eh bien... il n'y a pas de divergence avec la description de la documentation dans cet exemple... Regardez bien la citation de la documentation

Une variable statique peut être initialisée avec une constante ou une expression de type constante appropriée à son type , contrairement à une simple variable locale qui peut être initialisée avec n'importe quelle expression.


ou par une expressionconstante

int a= 1;
int b= a+1;

Cette initialisation est possible. Parce que la variable 'a' est initialisée par une constante et la variable 'b' est initialisée par une expression constante.

 
A100:

Il faut alors interdire les instances statiques des classes - car elles sont initialisées par la fonction constructeur

Faites attention à

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégies de trading

Bugs, bugs, questions

Alexey Viktorov, 2017.10.18 09:19

Pourquoi pensez-vous avoir changé, pourquoi est-ce inacceptable ? Veuillez l'utiliser à votre propre discrétion. Le problème est que lorsqu'une variable statique est initialisée par une fonction, l'initialisation est "mise en pause" et cette fonction est exécutée. Et dans l'exemple ci-dessus, il y a toujours une variable statique dans cette fonction qui n'a pas encore été initialisée. Ainsi, une variable initialisée par une fonction prend une valeur différente.
Malheureusement, je ne sais pas s'il est possible de déclarer et d'initialiser des variables statiques dans le constructeur, mais j'espère que vous me le direz. Et, d'après ce que je comprends, la séquence d'initialisation est très importante.
 
Alexey Viktorov:

Cette initialisation est possible. Parce que la variable 'a' est initialisée avec une constante, et la variable 'b' est initialisée avec une expression constante.

Ici, 'b' est initialisé NON par une expression constante. C'est pourquoi il est en contradiction avec les règles décrites dans la documentation.

Leproblème est que lorsqu' unevariable statique est initialisée par une fonction, l'initialisation est "mise en pause" et la fonction est exécutée. Dans l'exemple ci-dessus, il y a une variable statique dans cette fonction qui n'a pas encore été initialisée. Ainsi, une variable initialisée par une fonction prend une valeur différente.

Mais comment l'initialisation peut-elle être interrompue ? Toutes les opérations sont exécutées dans un ordre strict défini par la syntaxe du langage. Tout d'abord, la fonction est exécutée, puis la valeur renvoyée par cette fonction est transmise au constructeur de notre variable - c'est ce qu'on appelle l'initialisation. Mais l'opération d'initialisation est ignorée de manière flagrante par le compilateur dans ce cas, et le code continue de compiler comme si rien ne s'était passé. C'est inacceptable. C'est la même chose que si vous déclariez, par exemple, le tableau suivant int a[]= { f(), g(), h() } ; et cela compilerait, mais bien sûr sans initialiser quoi que ce soit.