Au revoir le robot - bonjour le marasme - page 7

 
Renat:
...

Test de cet exemple :

  • MQL4/MQL5 - donne des avertissements sur les erreurs potentielles

  • Visual Studio 2012, y compris l'analyse du code - rien, la qualité de l'analyse pour les erreurs potentielles est nulle. Ils ne s'en soucient pas puisqu'il n'y a pas de concurrents depuis longtemps.

  • PVS Studio - rapports correctement.

  • Lint - rapporte la même chose, mais le 'x' cache ...

    ...

Pavlick:

Je pense aussi que les messages sont absolument inutiles. Je ne suis pas un programmeur professionnel, mais ce genre d'absurdité dans µl me stresse. Je me demande si si les références à a et b sont constantes, PVS Studio générera-t-il un avertissement (pas moyen de le vérifier moi-même) ?

Néanmoins, il n'est pas mauvais d'aller d'abord au fond de l'alerte, puis de la citer comme argument. PVS Studio vous préviendra non pas parce que la variable globale est cachée, mais parce que a et b sont passés par une référence non constante mais ne sont pas modifiés. Dans ce cas, ils estiment que a et b doivent être transmis par une référence constante. Par exemple, les exemples suivants ne font pas se plaindre cet analyseur :

int a=1,b=2;
int sum(const int& a, const int& b){
        return(a+b);
}

int main(){
        return sum(a,b);
}

//-------------------------------------------------
int a=1,b=2;
int sum(int& a, int& b){
        ++a; ++b;
        return(a+b);
}

int main(){
        return sum(a,b);
}
 

Je suis bien conscient de ce que PVS nous reproche.

Encore une fois, nous n'avons pas le fardeau de la responsabilité de compiler des milliards de lignes de vieux code C/C++. Il appartient à leurs propres compilateurs de ne pas leur gâcher la tâche en générant des avertissements. Nous, en revanche, sommes responsables de la sécurité et du contrôle des erreurs de notre langage d'application, qui fonctionne avec de l'argent.

Seuls quelques pour cent des auteurs de code MQL4/5 sont des programmeurs professionnels (au sens propre du terme). Tous les autres sont juste des autodidactes et n'ont aucune idée de la façon dont ils écrivent le code.

Par exemple, après la migration vers la version actualisée de MQL4, nous avons dû passer en revue manuellement des milliers de sources dans la kodobase et corriger un nombre incroyable d'erreurs dans leur ancien code. Beaucoup d'erreurs ont été trouvées et montrées par le compilateur, même sans exécuter les programmes.

C'est pourquoi nous ne devrions pas prétendre émettre des avertissements mais corriger notre propre code.

 
Renat:

Je sais très bien ce que PVS nous reproche.

Encore une fois, nous n'avons pas le fardeau de la responsabilité de compiler des milliards de lignes de vieux code C/C++. Il appartient à leurs propres compilateurs de ne pas leur gâcher la tâche en générant des avertissements. Nous, en revanche, sommes responsables de la sécurité et du contrôle des erreurs de notre langage d'application, qui fonctionne avec de l'argent.

Seuls quelques pour cent des auteurs de code MQL4/5 sont des programmeurs professionnels (au sens propre du terme). Tous les autres sont juste des autodidactes et n'ont aucune idée de la façon dont ils écrivent le code.

Par exemple, après la migration vers la version actualisée de MQL4, nous avons dû passer en revue manuellement des milliers de sources dans la kodobase et corriger un nombre incroyable d'erreurs dans leur ancien code. Beaucoup d'erreurs ont été trouvées et montrées par le compilateur, même sans exécuter les programmes.

C'est pourquoi vous ne devez pas vous plaindre de l'émission d'avertissements, mais corriger votre code.


Si le tableau vous permet de manquer sa plage, il serait très bête de prendre des efforts comparables à ceux de l'écriture de l'indicateur lors de l'écriture de l'indicateur lui-même, mais seulement pour le calcul du début du calcul.

Vous n'avez pas besoin de creuser dans ce code, la moitié n'est pas corrigée, elle est cassée. Vous auriez pu simplement créer une propriété supplémentaire pour distinguer l'ancienne mql4, la nouvelle mql4 ou la nouvelle mql4 avec strict. Quelle taille prend l'ancien compilateur ? Je ne sais pas, mais probablement moins d'un mégaoctet, pas de problème pour le trimballer à l'ère des gigaoctets. Mais ici nous avons une sorte d'acte héroïque - la destruction de la base de code.

* * *

Avertissement

La déclaration de 'a' cache la déclaration globale à la ligne X

C'est un avertissement idiot. Si quelqu'un, dans le monde "supérieur", a des problèmes avec ce système, cela ne signifie pas que d'autres peuvent avoir de tels problèmes. Il y a une portée aux variables, ce que quelqu'un appelle variables est une affaire privée.

 
Integer:


Si l'on permet à un tableau de dépasser sa plage, il serait très bête, lors de l'écriture de l'indicateur, de faire des efforts comparables à ceux de l'écriture de l'indicateur lui-même, mais seulement pour calculer le début du calcul.

Vous auriez pu éviter de creuser dans ce code, la moitié n'est pas corrigée mais cassée. On aurait pu simplement créer une propriété supplémentaire pour distinguer l'ancien mql4, le nouveau ou le nouveau avec strict. Quelle taille prend l'ancien compilateur ? Je ne sais pas, mais probablement moins d'un mégaoctet, pas de problème pour le trimballer à l'ère des gigaoctets. Mais voici une sorte de travail héroïque accompli - pour détruire la base de code.

Exactement réparé, pas cassé.

Si une erreur s'est glissée après les modifications, c'est tout à fait possible - toute modification entraîne inévitablement de telles erreurs. Mais cela ne signifie pas que l'on puisse accrocher des erreurs isolées à un drapeau et gravir une montagne d'erreurs corrigées.


Le 'a' cache la déclaration globale à la ligne X

C'est un avertissement idiot. Si quelqu'un dans le monde "supérieur" a des problèmes avec elle, cela ne signifie pas que les autres peuvent avoir de tels problèmes. Il existe une zone de visibilité variable, ce que chacun appelle variable est une affaire privée.

Des gens étonnants qui se battent pour le droit de se photographier eux-mêmes. Il est particulièrement gratifiant qu'une personne écrive "laissez l'ancien compilateur tranquille" en toute sincérité.
 
simpleton:

Une erreur potentielle est une erreur potentielle parce qu'elle n'est pas nécessairement une erreur du tout.

Je ne sais pas, je ne sais pas. Nous avions l'habitude de mettre des mandats de niveau 4 ou 5 à la libération et de cocher la case pour compter les mandats comme des erreurs.

Nous nous sommes débarrassés d'avertissements vraiment stupides avec les pragmas, mais nous nous sommes quand même débarrassés d'eux.

 
Andrei01:

Cette remarque n'a pas de sens et ne fournit en principe aucune information utile au programmeur, car il n'y a pas de dissimulation de la variable "a", comme cela est affirmé.

1.cpp(3): remark #3280: declaration hides variable "a" (declared at line 1)
  int sum(int& a, int& b){        

Si le programmeur utilise délibérément la dissimulation, alors oui, cette remarque est dénuée de sens et ne fournit aucune information utile. Si, en revanche, la dissimulation a été faite accidentellement par négligence, la remarque permet de détecter l'erreur à un stade précoce.

Andrei01:

Le masquage ne se produit que lorsqu'une copie locale de la variable est créée, ce qui est également une action parfaitement légitime. Même si une erreur dans le code se produit soudainement à cause de cette dissimulation, elle est facilement trouvée précisément parce que la recherche trouve immédiatement le même nom. Si nous commençons à changer et à modifier les noms dans un modèle de fonction, qui est une "solution" à cette règle par la logique du compilateur, la situation de recherche d'erreurs deviendra beaucoup plus compliquée et la confusion sera grande dans la compréhension du code. Cela semble évident.

Lesvariables locales et les paramètres sont dans une seule portée, donc il n'est pas important qu'un paramètre ait ce nom ou une variable locale, mais dans tous les cas ce nom cache un nom dans la portée extérieure.

Le masquage n'a rien à voir avec les copies de variables, il a à voir avec les noms d'entités. Oui, même s'il s'agit de noms d'entités comme les types :

class A { };

void f(int a) {
        A x;
}

il compile :

$ icpc -c 1.cpp
$ 

Et ceci :

class A { };

void f(int A) {
        A x;
}

Ce n'est pas le cas :

$ icpc -c 1.cpp
1.cpp(4): error: expected a ";"
        A x;
          ^

compilation aborted for 1.cpp (code 2)
$ 

Parce que le nom A à l'intérieur d'une fonction n'est plus un nom de type, mais un nom de paramètre de variable. Le nom du type déclaré dans la portée externe est maintenant caché par le nom de la variable-paramètre. Vous pouvez en avoir un aperçu indirect lorsque vous voyez que ce code

class A { };

void f(int A) {
        A++;
}

compile bien :

$ icpc -c 1.cpp
$ 

Dans MQL4++, cela ne compile pas déjà au stade de la dissimulation du nom du type par le nom du paramètre de la variable, c'est-à-dire même avec un corps de fonction vide :

#property strict

class A { };
void f(int A) { }
void OnStart() { }

résultat :

'A' - structure identifier cannot be used       3.mq4   4       12
'A' - structure identifier cannot be used       3.mq4   4       12

Je ne sais pas pourquoi, mais je ne suis pas du tout surpris.

Pour le C++, en revanche, il n'y a aucun problème avec un tel code :

class A { };
void f(int A) { }

le résultat d'une tentative de compilation :

$ icpc -c 1.cpp
$ 

Cet exemple montre que le masquage est lié aux noms des entités et à rien d'autre.

Si la remarque n'est pas commutable, nous devons inventer toutes sortes de choses, comme truquer les noms. Mais si elle est tournante, comme dans le compilateur Intel, vous n'avez pas de tels problèmes.

Le problème dans MQL4++ ne concerne pas la fonctionnalité du compilateur elle-même concernant la détection des noms cachés dans les scopes imbriqués, mais l'immuabilité fondamentale de cette fonctionnalité.

 
Renat:

Il ne faut donc pas faire de déclarations sur les avertissements, mais corriger son propre code.

La plainte concernant les avertissements/marques en discussion, je pense, peut être une - sur leur non-exclusion de principe.

Et, bien sûr, vous ne pouvez pas dire au programmeur ce qu'il doit faire ou ne pas faire dans le langage.

 

De tels messages (cachant des variables globales) n'ont tout simplement pas de sens en C++ (mql a été déclaré c++ like, non ?). Voici pourquoi, par exemple :

struct S1{
    int val;
};

struct S2{};

template<typename _T>
struct SS : _T{
    int f() {int val; return val;}
};

int main(){
    SS<S1> q1; q1.f();
    SS<S2> q2; q2.f();
}
 
Pavlick:

De tels messages (cachant des variables globales) n'ont tout simplement pas de sens en C++ (mql a été déclaré c++ like, non ?). Voici pourquoi, par exemple :

struct S1{
    int val;
};

struct S2{};

template<typename _T>
struct SS : _T{
    int f() {int val; return val;}
};

int main(){
    SS<S1> q1; q1.f();
    SS<S2> q2; q2.f();
}

C++ a été pris ici parce que MQL4++ n'a pas de modèles de structure/classe - seulement des modèles de fonction ?

Je ne sais pas si les développeurs le savent, mais les modèles de classe sont également possibles dans MQL4++, mais avec des limitations importantes. En particulier, cet exemple peut être transposé à MQL4++ de la manière suivante (un paramètre est également utilisé au lieu d'une variable locale dans une méthode) :

#property strict

struct S1 { };
struct S2 { int val; };

template <typename T>
void f(T &t) {
  struct SS: public T {
    int f(int val) { return val; }
  } ss = {0}; // Переменная типа SS
}

void OnStart() {
  S1 s1; f(s1);
  S2 s2; f(s2);
}

Un seul avertissement concernant la dissimulation du nom s'affichera à la compilation :

'3.mq4' 3.mq4   1       1
struct has no members, size assigned to 1 byte  3.mq4   3       8
struct has no members, size assigned to 1 byte  3.mq4   8       10
declaration of 'val' hides member declaration at line 4 3.mq4   9       15
0 error(s), 3 warning(s)                1       4

Si la dernière ligne significative de OnStart() est commentée, l'avertissement concernant la dissimulation du nom disparaît.

 
simpleton:

C++ a été pris ici parce qu'il n'y a pas de modèles de structures/classes dans MQL4++ - seulement des modèles de fonctions ?

...

En général, oui, mais vous pouvez aussi utiliser des µl :

struct S1{
    int val;
};

struct S2{};

#define INSTANTIATE(_Name, _T)          \
    struct _Name : _T                   \
    {                                   \
        int f() {int val; return val;}; \
    }

INSTANTIATE(SS1, S1);
INSTANTIATE(SS2, S2);

void start(){
    SS1 q1; q1.f();
    SS2 q2; q2.f();
}
Raison: