Addio robot - ciao marasma - pagina 8

 
simpleton:

Le variabili locali e i parametri sono nello stesso ambito, quindi - non importa se un parametro ha questo nome o una variabile locale, ma in entrambi i casi questo nome nasconde il nome nell'ambito esterno.

Non in ogni caso. Quando una variabile viene passata per riferimento, non viene creata alcuna copia locale e il lavoro viene fatto direttamente sulla variabile passata. Allora, che tipo di nascondimento sta succedendo qui?
 
Andrei01:
Non in nessuna funzione. Quando una variabile viene passata per riferimento, non viene creata una copia locale e l'operazione viene eseguita direttamente con la variabile passata. Allora, che tipo di nascondimento sta succedendo qui?

È qui che avviene il nascondimento dei nomi. Tutto il resto - copia, non copia - è secondario. All'interno di una funzione, quando viene usato un nome di riferimento, il lavoro sarà fatto sull'oggetto a cui il riferimento si riferisce. Se si riferisce a un oggetto nell'ambito esterno, il lavoro sarà fatto con esso. Questo non è perché non c'è un nascondiglio del nome - il nascondiglio è presente, proprio come in altri casi - ma perché il riferimento punta a questo oggetto. Una funzione viene chiamata in questo modo. Passato su questo stesso oggetto per riferimento e ora punta ad esso. Quando si chiama e si passa al momento di chiamare un altro oggetto, lo stesso codice di funzione funzionerà con un altro oggetto.

Stavo facendo un esempio con un nome di tipo e un nome di variabile, cioè con entità di natura il più possibile diversa, per mostrare che la clandestinità si applica/riferisce ai nomi, e tutto il resto è secondario.

Tuttavia, quando ho cercato di creare un altro esempio in MQL4++ su questo tema, ho scoperto per caso che in MQL4++ viene creato un ambito aggiuntivo per i parametri. L'ambito delle variabili locali è già annidato in esso:

#property strict

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

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

void OnStart() {
  f(3);
}

Questo esempio è COMPILATO con un avvertimento caratteristico:

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

E in seguito viene eseguito con successo:

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

È ovvio che in MQL4++ viene creato un altro ambito "strato" per i parametri. Per questo è possibile dichiarare una variabile locale con lo stesso nome del parametro.

In C/C++ non c'è questo "strato":

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

Il compilatore spiega popolarmente che c'è già una variabile con quel nome nello scope:

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

Cioè, l'ambito dei parametri della funzione e le sue variabili locali sono la stessa cosa.

Perché non è così in MQL4++ e per quale scopo non lo è - è, naturalmente, una domanda interessante...

 
simpleton:

void f(int a)

Questo esempio si compila con un avvertimento caratteristico:

Questo caso discute il caso del passaggio di una variabile per riferimento e un avvertimento errato, non la creazione di una copia locale.

void f(int& a)
 

Ho letto solo i primi post.

Naturalmente, anche sotto il tappeto le cose non vanno del tutto lisce. Ci sono alcune lacune degli sviluppatori qui nel testare il prodotto che raggiunge l'utente finale. Tuttavia, anche MT4 non è forte nelle strategie multi-valuta (test), e ha bisogno di essere raffinato. Quindi spero che un giorno sarà così, dopo tutto.

Se non sapete programmare, non andate in quello vero, e usate la demo per ora. Come sempre un cattivo ballerino si mette in mezzo alle "palle", compreso l'oro e il rosa.

Buona fortuna!


 
Andrei01:

Questo è un caso di passaggio di una variabile per riferimento e un avvertimento errato, non la creazione di una copia locale.

void f(int& a)

Non ha molta importanza in termini di natura dell'avvertimento. Inoltre, non importa solo se una variabile è passata per riferimento o per valore, ma che tipo è:

#property strict

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

Il codice si compila, viene generato l'avvertimento di cui state parlando:

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

Per qualche motivo non volete capirlo.

L'avvertimento in sé non è affatto errato. Inoltre, ad una rapida occhiata, il monitoraggio dell'ambito in MQL4++ è sorprendentemente ben fatto rispetto a come sono fatte altre cose.

Gli avvertimenti, pur essendo veri, non sono pratici, eppure non si possono spegnere - è di questo che si tratta. E non si tratta affatto della trasmissione nel link.

 
simpleton:

Per quanto riguarda la natura dell'avvertimento, questo è irrilevante. Inoltre, non importa se la variabile è passata per riferimento o per valore

C'è una grande differenza nell'essenza dell'avvertimento tra passare la variabile stessa e modificarla in una funzione e crearne una copia, mentre la variabile stessa rimane invariata.

E il fatto che gli avvisi non possono essere disabilitati o personalizzati, è un classico stile proprietario MC - "non lasciare":))) Non ci si può fare niente, ma si può solo accettare umilmente e docilmente perché questo stile è stato elevato al rango di attributo religioso... Non ha senso cercare una logica o un qualsiasi tipo di giustizia qui. ))

 

Ugh ugh ho tutta la roba di methaquot che funziona come un orologio.

Nessuna lamentela.

 
simpleton:

Un errore potenziale è proprio questo, un errore potenziale non è necessariamente un errore. Pertanto, l'affermazione che "significa che dobbiamo correggere questi errori" è sbagliata, perché potrebbero NON essere affatto errori.

...

Queste persone sono dei geek. Questi idioti combattono il compilatore come un mulino a vento senza capire la cosa principale: il compilatore è tuo alleato! Rallegratevi quando il compilatore giura sui frammenti di codice potenzialmente non sicuri. Rallegratevi anche se l'applicazione si blocca subito dopo il lancio con una stringa di errore. Ma Dio non voglia che si ottenga un codice ingestibile quando non ci sono errori o avvertimenti e il programma sembra funzionare bene ma di tanto in tanto si verificano strani glitch la cui causa non può essere rintracciata da nessuna parte. In questi momenti ci si copre di vapore e si cominciano a sognare errori come"puntatore non valido" o "divisione per zero".
 
C-4:
Ma Dio non voglia che si ottenga un codice ingestibile quando non ci sono errori o avvertimenti e il programma sembra funzionare bene ma ogni tanto si verificano strani bug, la cui ragione non può essere trovata da nessuna parte. In questi momenti ci si copre di vapore e si cominciano a sognare errori come "puntatore non valido" o "divisione per zero".

Il compilatore non ha niente a che fare con questo, è la tipica scrittura buggy quando non ci sono controlli di test in frammenti di codice pericolosi dove sono possibili stati indefiniti o errati, ecco perché appaiono i glitch.

I controlli funzionali del codice non hanno nulla a che fare con il compilatore e non ha senso aspettarselo dall'inizio.

Di nuovo, i programmatori professionisti di solito non guardano gli avvertimenti perché conoscono la logica del compilatore, mentre i compilatori sono inutili nel controllare la funzionalità del codice.

 
Andrei01:

C'è una grande differenza, in sostanza, tra passare la variabile stessa e modificarla in una funzione e farne una copia, mentre la variabile stessa rimane invariata.

Qui è solo un diverso tipo di avvertimento. A proposito di nascondere i nomi.

La variabile stessa non viene passata. Viene passato un riferimento ad esso.

Motivazione: