Adeus robô - olá marasmus - página 7

 
Renat:
...

Teste deste exemplo:

  • MQL4/MQL5 - dá avisos sobre possíveis erros

  • Visual Studio 2012, incluindo Análise de Código - nada, a qualidade da análise para erros potenciais é zero. Eles não se incomodam, já que não há concorrentes há muito tempo.

  • PVS Studio - relata corretamente.

  • Lint - relata a mesma coisa, mas o 'x' esconde...

    ...

Pavlick:

Eu acho que as mensagens também são absolutamente inúteis. Não sou um programador profissional, mas este tipo de bobagem em µl me estressa. Será que as referências a e b são constantes, será que o PVS Studio irá gerar um aviso (não há maneira de verificá-lo eu mesmo)?

Mesmo assim, não é uma coisa ruim entrar primeiro na essência da advertência e depois dar-lhe como argumento. O PVS Studio advertirá você não porque a variável global está oculta, mas porque a e b são passadas por uma referência não-constante, mas não são modificadas. Nesse caso, eles acreditam que a e b devem ser passadas por uma referência constante. Por exemplo, os exemplos a seguir não fazem com que este analisador reclame:

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

Estou bem ciente do que a PVS está nos culpando.

Mais uma vez, não temos o peso da responsabilidade de compilar bilhões de linhas do antigo código C/C++. Cabe a seus próprios compiladores não estragar seus negócios gerando avisos. Nós, por outro lado, temos a responsabilidade pela segurança e controle de erros de nossa linguagem de aplicação, que funciona com dinheiro.

Apenas poucos por cento dos autores do código MQL4/5 são programadores profissionais (no verdadeiro sentido da palavra). Todos os demais são apenas autodidatas e não têm idéia do quanto escrevem mal o código.

Por exemplo, após a migração para a MQL4 atualizada, tivemos que arar manualmente milhares de fontes na kodobase e corrigir um número incrível de erros em seu código antigo. Muitos erros foram encontrados e mostrados pelo compilador, mesmo sem executar os programas.

É por isso que não devemos fazer reivindicações sobre a emissão de advertências, mas consertar nosso próprio código.

 
Renat:

Estou bem ciente do que a PVS está nos culpando.

Mais uma vez, não temos o peso da responsabilidade de compilar bilhões de linhas do antigo código C/C++. Cabe a seus próprios compiladores não estragar seus negócios gerando avisos. Nós, por outro lado, temos a responsabilidade pela segurança e controle de erros de nossa linguagem de aplicação, que funciona com dinheiro.

Apenas poucos por cento dos autores do código MQL4/5 são programadores profissionais (no verdadeiro sentido da palavra). Todos os demais são apenas autodidatas e não têm idéia do quanto escrevem mal o código.

Por exemplo, após a migração para a MQL4 atualizada, tivemos que arar manualmente milhares de fontes na kodobase e corrigir um número incrível de erros em seu código antigo. Muitos erros foram encontrados e mostrados pelo compilador, mesmo sem executar os programas.

É por isso que você não deve reclamar sobre a emissão de avisos, mas consertar seu código.


Se a matriz permite que você perca seu alcance, seria muito tolo fazer esforços comparáveis aos de escrever o indicador ao escrever o próprio indicador, mas apenas para o cálculo do início do cálculo.

Você não precisa cavar através deste código, metade dele não está consertado, está quebrado. Você poderia ter acabado de fazer uma propriedade adicional para distinguir entre mql4 antigo, mql4 novo ou mql4 novo com rigor. Qual é o tamanho do antigo compilador? Não sei, mas provavelmente menos de um megabyte, não há problema em carregá-lo na era dos gigabytes. Mas aqui temos uma espécie de ato heróico - a destruição da base de código.

* * *

Advertência

Declaração de 'a' esconde declaração global na linha X

Este é um aviso idiota. Se alguém lá fora no mundo "superior" tem problemas com ele, isso não significa que outros possam ter tais problemas. Há um escopo para as variáveis, o que alguém chama de variáveis é um assunto privado.

 
Integer:


Se for permitido que uma matriz ultrapasse seu intervalo, seria muito tolo ao escrever o indicador para fazer esforços comparáveis aos de escrever o próprio indicador, mas apenas para calcular o início do cálculo.

Você poderia ter evitado cavar através deste código, metade dele não é fixo, mas quebrado. Poderia ter acabado de fazer uma propriedade extra para distinguir entre o antigo mql4, novo ou novo com rigor. Qual é o tamanho do antigo compilador? Não sei, mas provavelmente menos de um megabyte, não há problema em carregá-lo na era dos gigabytes. Mas aqui está uma espécie de trabalho heróico feito - destruir a base de código.

Exatamente fixo, não quebrado.

Se um erro entrar após a edição, é totalmente possível - qualquer edição inevitavelmente leva a tais erros. Mas isso não significa que você possa pendurar erros individuais em uma bandeira e escalar uma montanha de erros corrigidos.


O 'a' esconde a declaração global na linha X

Este é um aviso idiota. Se alguém no mundo "superior" tem problemas com ele, isso não significa que outros possam ter tais problemas. Existe uma área de visibilidade de variáveis, o que qualquer um chama de variáveis é um assunto privado.

Pessoas incríveis lutando pelo direito de se autodisparar. É especialmente gratificante que uma pessoa escreva "deixe o velho compilador em paz" com toda a seriedade.
 
simpleton:

Um erro potencial é um erro potencial porque não é necessariamente um erro em absoluto.

Eu não sei, eu não sei. Costumávamos ter uma regra prática para colocar os mandados de nível 4 ou 5 na liberação e marcar a caixa para contar os mandados como erros.

Nos livramos de avisos realmente estúpidos com pragmas, mas ainda assim nos livramos deles.

 
Andrei01:

Esta observação não faz sentido e não fornece nenhuma informação útil ao programador em princípio, pois não há ocultação da variável "a", como se afirma.

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

Se o programador usa deliberadamente a ocultação, então sim, esta observação não tem sentido e não fornece nenhuma informação útil. Se, por outro lado, a ocultação foi feita acidentalmente por negligência, a observação nos permite detectar o erro em uma fase inicial.

Andrei01:

A ocultação ocorre somente quando uma cópia local da variável é criada, o que também é uma ação perfeitamente legítima. Mesmo que de repente ocorra um erro no código por causa deste esconderijo, ele é facilmente encontrado precisamente porque a busca encontra imediatamente o mesmo nome. Se começarmos a mudar e alterar os nomes em um modelo de função, que é uma "solução" para esta regra pela lógica do compilador, a situação de busca de erros se tornará muito mais complicada e a confusão abundará na compreensão do código. Parece óbvio.

As variáveis e parâmetroslocais estão em um escopo, portanto não importa se um parâmetro tem este nome ou uma variável local, mas em qualquer caso este nome esconde um nome no escopo externo.

Esconder nada tem a ver com cópias de variáveis, tem a ver com nomes de entidades. Sim, ainda que esteja relacionado a nomes de entidades como tipos:

class A { };

void f(int a) {
        A x;
}

compila:

$ icpc -c 1.cpp
$ 

E isto:

class A { };

void f(int A) {
        A x;
}

Não tem:

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

compilation aborted for 1.cpp (code 2)
$ 

Porque o nome A dentro de uma função não é mais um nome de tipo, mas um nome de parâmetro variável. O nome do tipo declarado no escopo externo é agora escondido pelo nome do parâmetro variável. Você pode ter um vislumbre indireto disto, descobrindo que este código

class A { };

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

compila bem:

$ icpc -c 1.cpp
$ 

Na MQL4++ isto não se compila já na fase de esconder o nome do tipo por nome de parâmetro variável, ou seja, mesmo com um corpo de função vazio:

#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

Não sei por que, mas não estou nada surpreso.

Para C++, por outro lado, não há nenhum problema com tal código:

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

resultado de uma tentativa de compilação:

$ icpc -c 1.cpp
$ 

Este exemplo mostra que a ocultação está relacionada a nomes de entidades e não a nada mais.

Se a observação não puder ser trocada, temos que inventar todo tipo de coisa, como o aliasing. Mas se for girável, como no compilador Intel, você não tem tais problemas.

O problema na MQL4++ não é com a funcionalidade do compilador em si no que diz respeito à detecção de nomes escondidos em âmbitos aninhados, mas com a inoperabilidade fundamental desta funcionalidade.

 
Renat:

Portanto, não se deve fazer reivindicações sobre as advertências, mas consertar o próprio código.

A reclamação sobre os avisos/observações em discussão, eu acho, pode ser uma só - sobre sua não-exclusividade em princípio.

E, é claro, você não pode dizer ao programador o que fazer dentro da língua e o que não fazer.

 

Tais mensagens (ocultando variáveis globais) simplesmente não fazem sentido em C++ (o mql foi declarado como c++ como, certo?). Por exemplo, aqui está o porquê:

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:

Tais mensagens (ocultando variáveis globais) simplesmente não fazem sentido em C++ (o mql foi declarado como c++ como, certo?). Por exemplo, aqui está o porquê:

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+++ foi tomada aqui porque a MQL4+++ não tem modelos de estrutura/classe - apenas modelos de função?

Não tenho certeza se os desenvolvedores estão cientes disso, mas os modelos de classe também são possíveis na MQL4++, embora com limitações significativas. Em particular, este exemplo pode ser transposto para a MQL4++ da seguinte forma (também é usado um parâmetro em vez de uma variável local em um 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);
}

Um único aviso sobre como esconder o nome será exibido na compilação:

'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

Se a última linha significativa em OnStart() for comentada, o aviso de esconder o nome desaparece.

 
simpleton:

C+++ foi tomado aqui porque não há modelos de estrutura/classe na MQL4++ - apenas modelos de função?

...

Geralmente, sim, mas você também pode usar µ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ão: