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

 
simpleton:

As variáveis e parâmetros locais estão no mesmo escopo, portanto - não importa se um parâmetro tem este nome ou uma variável local, mas de qualquer forma este nome esconde o nome no escopo externo.

Em todo caso, não. Ao passar uma variável por referência, nenhuma cópia local é criada e o trabalho é feito diretamente com a variável passada. Então, que tipo de esconderijo está acontecendo aqui?
 
Andrei01:
Não em nenhuma função. Quando uma variável é passada por referência, uma cópia local não é criada e a operação é realizada diretamente com a variável passada. Então, que tipo de esconderijo está acontecendo aqui?

É aqui que ocorre a ocultação de nomes. Tudo o resto - cópia, não cópia - é secundário. Dentro de uma função, quando um nome de referência é usado, a operação será com o objeto ao qual a referência se refere. Se se referir a um objeto no escopo externo, o trabalho será feito com ele. Isto não porque não há ocultação de nomes - a ocultação está presente, assim como em outros casos - mas porque os pontos de referência para este objeto. Uma função é chamada desta forma. Transmitiu este mesmo objeto por referência e agora ele aponta para ele. Ao chamar e passar no momento de chamar outro objeto, o mesmo código de função irá funcionar com outro objeto.

Eu estava dando um exemplo com um nome do tipo e um nome variável, ou seja, com entidades que são de natureza tão diferente quanto possível, para mostrar que a ocultação se aplica/referências a nomes, e tudo mais é secundário.

Entretanto, ao tentar criar outro exemplo na MQL4++ sobre este tema, descobri acidentalmente que um escopo adicional é criado para parâmetros na MQL4++. O escopo das variáveis locais já está aninhado nele:

#property strict

void f(int a) {
  int saved = a;
  int a = a + 1;

  Print("saved = " , saved, ", a = ", a);
}

void OnStart() {
  f(3);
}

Este exemplo é COMPILADO com um aviso característico:

declaration of 'a' hides local declaration at line 3    3.mq4   5       7

E mais tarde é executado com sucesso:

23:52:22 Script 3 EURUSDm,H1: loaded successfully
23:52:22 3 EURUSDm,H1: initialized
23:52:22 3 EURUSDm,H1: saved = 3, a = 4
23:52:22 3 EURUSDm,H1: uninit reason 0
23:52:22 Script 3 EURUSDm,H1: removed

É óbvio que outro escopo de "camada" é criado para parâmetros na MQL4++. É por isso que é possível declarar uma variável local com o mesmo nome que o parâmetro.

Em C/C++ não existe tal "camada":

void f(int a) {
  int saved = a;
  int a = a + 1;
}

O compilador explica popularmente que já existe uma variável com esse nome no escopo:

$ icpc -c 1.cpp
1.cpp(3): error: "a" has already been declared in the current scope
    int a = a + 1;
        ^

Ou seja, o escopo dos parâmetros de função e suas variáveis locais são uma e a mesma coisa.

Por que não é assim na MQL4++ e para que fim não é - é, naturalmente, uma pergunta interessante...

 
simpleton:

void f(int a)

Este exemplo COMPLETA com um aviso característico:

Este caso discute o caso de passar uma variável por referência e uma advertência errada, não a criação de uma cópia local.

void f(int& a)
 

Eu só li os primeiros posts.

É claro que as coisas também não correm muito bem debaixo do tapete. Há alguns lapsos dos desenvolvedores aqui no teste do produto que chega ao usuário final. Entretanto, também o MT4 não é forte em estratégias de múltiplas moedas (testes), e as necessidades, precisam ser refinadas. Por isso, espero que seja um dia, afinal de contas.

Se você não sabe como programar, não vá para o real e use a demonstração por enquanto. Como sempre, um mau bailarino fica no caminho das "bolas", incluindo ouro e rosa.

Boa sorte!


 
Andrei01:

Este é um caso de passar uma variável por referência e um aviso errado, não criando uma cópia local.

void f(int& a)

Isso não importa realmente em termos da natureza do aviso. Além disso, não importa apenas se uma variável é passada por referência ou por valor, mas que tipo ela é:

#property strict

int a; // line 3
class A { };
void f(A *&a) { } // line 5
void OnStart() { }

O código compila, o aviso que você está discutindo é gerado:

declaration of 'a' hides global declaration at line 3   3.mq4   5       12

Por alguma razão, você não quer entender isso.

O aviso em si não é de forma alguma defeituoso. Além disso, num relance, o acompanhamento do escopo na MQL4++ é surpreendentemente bem feito em comparação com a forma como outras coisas são feitas.

Os avisos, embora verdadeiros, não são práticos, e ainda assim não se pode desligá-los - é disso que se trata. E de forma alguma a transmissão do link.

 
simpleton:

Em termos da natureza da advertência, isto é irrelevante. Além disso, não importa se a variável é passada por referência ou por valor

Há uma grande diferença na essência do aviso entre passar a própria variável e modificá-la em uma função e criar uma cópia da mesma, enquanto a própria variável permanece inalterada.

E o fato de que os avisos não podem ser desativados ou personalizados, é um estilo clássico de propriedade MC - "não deixar":))) Não há nada que você possa fazer, mas você só pode humildemente e mansamente aceitar, porque este estilo foi elevado ao status de atributo religioso... Não adianta procurar a lógica ou qualquer tipo de justiça aqui. ))

 

Ugh ugh ugh tenho todas as coisas de metaquot funcionando como um relógio.

Nenhuma reclamação.

 
simpleton:

Um erro potencial é apenas isso, um erro potencial não é necessariamente um erro em absoluto. Portanto, a afirmação de que "isso significa que temos que corrigir esses erros" está errada, porque eles podem NÃO ser erros de forma alguma.

...

Essas pessoas são nerds. Tais idiotas lutam contra o compilador como um moinho de vento que não entende o principal: o compilador é seu aliado! Alegre-se quando o compilador jurar por fragmentos de código potencialmente inseguros. Alegre-se mesmo que a aplicação trave logo após o lançamento com uma cadeia de erros. Mas Deus proíbe que você receba um código incontrolável quando não há erros ou avisos e o programa parece funcionar bem, mas estranhas falhas ocorrem de tempos em tempos, cuja causa não pode ser rastreada em nenhum lugar. Nesses momentos, você fica coberto de vapor e começa a sonhar com erros como"ponteiro inválido" ou "divisão por zero".
 
C-4:
Mas Deus proíbe que você receba um código incontrolável quando não há erros ou avisos e o programa parece funcionar bem, mas estranhos bugs ocorrem de vez em quando, cuja razão não pode ser encontrada em nenhum lugar. Nesses momentos, você fica coberto de vapor e começa a sonhar com erros como "ponteiro inválido" ou "divisão por zero".

O compilador não tem nada a ver com isso, é típica programação de buggy quando não há verificações de teste em fragmentos de código perigosos onde são possíveis estados indefinidos ou errôneos, por isso as falhas aparecem.

As verificações de código funcional não têm nada a ver com o compilador e não vale a pena esperar isso desde o início.

Novamente os programadores profissionais normalmente não olham para os avisos porque conhecem a lógica do compilador enquanto os compiladores são inúteis na verificação da funcionalidade do código.

 
Andrei01:

Há uma grande diferença em essência entre passar a própria variável e modificá-la em uma função e fazer uma cópia da mesma, e a própria variável permanece inalterada.

Aqui é apenas um tipo diferente de aviso. Sobre como esconder nomes.

A variável em si não é passada. Uma referência a ela é passada.