Adiós robot - hola marasmo - página 7

 
Renat:
...

Prueba de este ejemplo:

  • MQL4/MQL5 - da advertencias sobre posibles errores

  • Visual Studio 2012, incluyendo el Análisis de Código - nada, la calidad del análisis para posibles errores es nula. No se molestan ya que no hay competidores durante mucho tiempo.

  • PVS Studio - informa correctamente.

  • Lint - informa de lo mismo, pero la 'x' se esconde...

    ...

Pavlick:

Yo también creo que los mensajes son absolutamente inútiles. No soy un programador profesional, pero este tipo de tonterías en µl me estresan. Me pregunto si las referencias a y b son constantes, ¿Generará PVS Studio una advertencia (no hay manera de comprobarlo yo mismo)?

Aun así, no es malo entrar primero en la esencia de la advertencia y luego plantearla como argumento. PVS Studio le avisará no porque la variable global esté oculta, sino porque a y b se pasan por una referencia no constante pero no se modifican. En ese caso, creen que a y b deben pasar por una referencia constante. Por ejemplo, los siguientes ejemplos no hacen que este analizador se queje:

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);
}
 

Soy muy consciente de lo que nos achaca PVS.

Una vez más, no tenemos la carga de la responsabilidad de compilar miles de millones de líneas de código C/C++ antiguo. Depende de sus propios compiladores no estropear su negocio generando advertencias. Nosotros, en cambio, tenemos la responsabilidad de la seguridad y el control de errores de nuestro lenguaje de aplicación, que trabaja con dinero.

Sólo un pequeño porcentaje de los autores de código MQL4/5 son programadores profesionales (en el verdadero sentido de la palabra). Todos los demás son autodidactas y no tienen ni idea de lo mal que escriben el código.

Por ejemplo, después de la migración al MQL4 actualizado, tuvimos que revisar manualmente miles de fuentes en el kodobase y corregir un número increíble de errores en su código antiguo. El compilador ha encontrado y mostrado muchos errores, incluso sin ejecutar los programas.

Por ello, no debemos reclamar la emisión de avisos, sino arreglar nuestro propio código.

 
Renat:

Soy muy consciente de lo que nos achaca PVS.

Una vez más, no tenemos la responsabilidad de compilar miles de millones de líneas de código C/C++ antiguo. Depende de sus propios compiladores no estropear su negocio generando advertencias. Nosotros, en cambio, tenemos la responsabilidad de la seguridad y el control de errores de nuestro lenguaje de aplicación, que trabaja con dinero.

Sólo un pequeño porcentaje de los autores de código MQL4/5 son programadores profesionales (en el verdadero sentido de la palabra). Todos los demás son autodidactas y no tienen ni idea de lo mal que escriben el código.

Por ejemplo, después de la migración al MQL4 actualizado, hemos tenido que revisar manualmente miles de fuentes en el kodobase y corregir un número increíble de errores en su código antiguo. El compilador ha encontrado y mostrado muchos errores, incluso sin ejecutar los programas.

Por eso no hay que quejarse de la emisión de avisos, sino arreglar el código.


Si la matriz le permite perder su rango, sería muy tonto tomar esfuerzos comparables a los de escribir el indicador cuando se escribe el indicador en sí, pero sólo para el cálculo del inicio del cálculo.

No hay que rebuscar en este código, la mitad no está arreglada, está rota. Podrías haber hecho simplemente una propiedad adicional para distinguir entre mql4 antiguo, mql4 nuevo o mql4 nuevo con estricto. ¿Qué tamaño tiene el antiguo compilador? No lo sé, pero probablemente menos de un megabyte, no hay problema para cargarlo en la era de los gigabytes. Pero aquí tenemos una especie de acto heroico: la destrucción del código base.

* * *

Advertencia

La declaración de 'a' oculta la declaración global en la línea X

Esta es una advertencia idiota. Si alguien en el mundo "superior" tiene problemas con él, no significa que otros puedan tenerlos. Las variables tienen un ámbito de aplicación, lo que alguien llama variables es un asunto privado.

 
Integer:


Si se permite que un array se salga de su rango, sería muy tonto que al escribir el indicador se hicieran esfuerzos comparables a los de escribir el propio indicador, pero sólo para calcular el punto de partida del cálculo.

Podrías haberte evitado rebuscar en este código, la mitad no está arreglada sino rota. Podría haber hecho una propiedad extra para distinguir entre mql4 viejo, nuevo o nuevo con estricto. ¿Qué tamaño tiene el antiguo compilador? No lo sé, pero probablemente menos de un megabyte, no hay problema para cargarlo en la era de los gigabytes. Pero aquí hay una especie de trabajo heroico hecho - para destruir el código base.

Exactamente fijo, no roto.

Si un error se deslizó después de la edición, es totalmente posible - cualquier edición conduce inevitablemente a tales errores. Pero eso no significa que se puedan colgar errores individuales en una bandera y escalar una montaña de corregidos.


La 'a' oculta la declaración global en la línea X

Esta es una advertencia idiota. Si alguien del mundo "superior" tiene problemas con él, no significa que otros puedan tenerlos. Hay un área de visibilidad de las variables, lo que cada uno llama variables es un asunto privado.

Gente increíble luchando por el derecho a autodisparar. Es especialmente gratificante que una persona escriba "deja el viejo compilador en paz" con toda seriedad.
 
simpleton:

Un error potencial es un error potencial porque no es necesariamente un error.

No lo sé, no lo sé. Solíamos tener la regla de poner las órdenes de nivel 4 o 5 en la liberación y marcar la casilla para contar las órdenes como errores.

Nos hemos librado de advertencias realmente estúpidas con pragmas, pero aún así nos hemos librado de ellas.

 
Andrei01:

Esta observación carece de sentido y, en principio, no aporta ninguna información útil al programador, ya que no hay ocultación de la variable "a", como se afirma.

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

Si el programador utiliza deliberadamente la ocultación, entonces sí, esta observación no tiene sentido y no aporta ninguna información útil. Si, por el contrario, la ocultación se hizo accidentalmente por negligencia, la observación permite detectar el error en una fase temprana.

Andrei01:

La ocultación sólo se produce cuando se crea una copia local de la variable, lo que también es una acción perfectamente legítima. Incluso si de repente se produce un error en el código debido a esta ocultación, se encuentra fácilmente precisamente porque la búsqueda encuentra inmediatamente el mismo nombre. Si empezamos a cambiar y alterar los nombres en una plantilla de función, que es una "solución" a esta regla por la lógica del compilador, la situación de búsqueda de errores se volverá mucho más complicada y abundará la confusión en la comprensión del código. Parece obvio.

Lasvariables locales y los parámetros están en un solo ámbito, por lo que no importa si un parámetro tiene este nombre o una variable local, pero en cualquier caso este nombre oculta un nombre en el ámbito externo.

La ocultación no tiene nada que ver con las copias de las variables, sino con los nombres de las entidades. Sí, aunque esté relacionado con nombres de entidades como los tipos:

class A { };

void f(int a) {
        A x;
}

compila:

$ icpc -c 1.cpp
$ 

Y esto:

class A { };

void f(int A) {
        A x;
}

No es así:

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

compilation aborted for 1.cpp (code 2)
$ 

Porque el nombre A dentro de una función ya no es un nombre de tipo, sino un nombre de parámetro de variable. El nombre del tipo declarado en el ámbito externo queda ahora oculto por el nombre de la variable-parámetro. Se puede obtener una visión indirecta de esto al descubrir que este código

class A { };

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

compila bien:

$ icpc -c 1.cpp
$ 

En MQL4++ esto no compila ya en la etapa de ocultar el nombre del tipo por el nombre de la variable-parámetro, es decir, incluso con un cuerpo de función vacío:

#property strict

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

resultado:

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

No sé por qué, pero no me sorprende en absoluto.

Para C++, en cambio, no hay ningún problema con ese código:

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

resultado de un intento de compilación:

$ icpc -c 1.cpp
$ 

Este ejemplo muestra que la ocultación está relacionada con los nombres de las entidades y no con nada más.

Si la observación no es conmutable, tenemos que inventar todo tipo de cosas, como falsear los nombres. Pero si se puede girar, como en el compilador de Intel, no se tienen esos problemas.

El problema en MQL4++ no es con la funcionalidad del compilador en sí mismo en lo que respecta a la detección de nombres ocultos en ámbitos anidados, sino con la inoperabilidad fundamental de esta funcionalidad.

 
Renat:

Por lo tanto, no hay que hacer afirmaciones sobre las advertencias, sino arreglar el propio código.

La queja sobre las advertencias/observaciones que se discuten, creo que puede ser una: sobre su, en principio, no excluibilidad.

Y, por supuesto, no se puede decir al programador lo que debe hacer dentro del lenguaje y lo que no.

 

Tales mensajes (ocultando variables globales) simplemente no tienen sentido en C++ (mql fue declarado como c++, ¿verdad?). Por ejemplo, esta es la razón:

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:

Tales mensajes (ocultando variables globales) simplemente no tienen sentido en C++ (mql fue declarado como c++, ¿verdad?). Por ejemplo, esta es la razón:

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++ fue tomado aquí porque MQL4++ no tiene plantillas de estructura/clase - sólo plantillas de función?

No estoy seguro de si los desarrolladores son conscientes de ello, pero las plantillas de clase también son posibles en MQL4++, aunque con importantes limitaciones. En particular, este ejemplo puede ser transpuesto a MQL4++ de la siguiente manera (también se utiliza un parámetro en lugar de una variable local en un método):

#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);
}

En la compilación aparecerá una única advertencia sobre la ocultación del nombre:

'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 se comenta la última línea significativa de OnStart(), desaparece la advertencia sobre la ocultación del nombre.

 
simpleton:

C++ fue tomado aquí porque no hay plantillas de estructura/clase en MQL4++ - sólo plantillas de función?

...

En general, sí, pero también se pueden utilizar µ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();
}
Razón de la queja: