Errori, bug, domande - pagina 2725

 
Vict:

Pensi che il tuo Sharp sia apparso in un campo pulito? Radicata in C, la struttura è un contenitore muto senza zucchero extra.

Beh, l'uomo si è evoluto da una scimmia. Ma questo non significa che l'uomo sia una scimmia stupida "senza zucchero extra", vero? ) Ho già spiegato che in effetti le strutture MQL = strutture C#, con una piccola differenza: in C# possono ancora implementare interfacce. interfacce, Carl! )

Come può essere così sicuro? Chiamare una funzione da un'altra unità di traduzione/un altro modulo/cicli/compilatore fuori sintonia/... . Non sopravvalutate le capacità dell'ottimizzatore. Questa non è l'ottimizzazione Copy elision che i compilatori sono obbligati a fare. Se gli ottimizzatori diventano così intelligenti e smette di costare qualcosa, scriveranno nel prossimo standard C: "l'inizializzazione di default non lascia un oggetto in stato indefinito".

Perché è la cosa più banale e primitiva che non si può nemmeno chiamare ottimizzazione. Penso che tutti i compilatori lo facciano di default anche in modalità Debug. Cosa può essere più facile? Durante il parsing del codice, devi tracciare l'accesso alle variabili. Se c'è un'operazione di scrittura ripetuta e non c'è stata alcuna operazione di lettura, allora taglia la voce precedente.

Puoi ignorarlo, ma poi non sorprenderti che i codificatori decenti ti guardino come un codificatore di merda quando vedono le tue strutture piene di funzioni

Piuttosto chiamerei il tuo approccio all'operazione non inizializzata "shit-coding". Qual è la qualità principale che deve possedere un programma per computer? La stabilità. Con gli stessi dati di input deve dare risultati immutabili. E tu proponi di dimenticartene. Da qualche parte hai dimenticato di inizializzare una variabile, da qualche parte hai aggiunto un nuovo campo alla struttura che è diventato non inizializzato in tutto il programma, e il programma è andato avanti. Il programma funziona così e così...

Il linguaggio C è stato creato in un passato lontano quando le capacità dell'hardware erano molto scarse, quindi gran parte del lavoro di ottimizzazione era lasciato al programmatore. Se sei così pruriginoso, perché ti riferisci al C e non all'Assembler per esempio? Codifica i sistemi di trading in Assembler. Sono sicuro che saranno i più veloci, forse anche più avanti del mercato)

 
Alexey Navoykov:

Perché è la cosa più banale e primitiva, che difficilmente può essere chiamata ottimizzazione. Penso che tutti i compilatori lo facciano di default anche in modalità Debug. Cosa potrebbe essere più facile? Mentre si analizza il codice, monitorare l'accesso alle variabili. Se c'è un'operazione di scrittura ripetuta e non c'è stata alcuna operazione di lettura, allora taglia la voce precedente.

Se il programma fosse completamente prevedibile in fase di compilazione, non dovrebbe essere eseguito affatto in fase di esecuzione. Dovrebbe per definizione prendere qualcosa dal mondo esterno e produrre un risultato basato su di esso, e questa è l'incertezza che ostacola l'ottimizzatore. Un altro segreto - le librerie condivise sono collegate con l'applicazione in runtime, l'ottimizzatore non può tracciare nulla lì. Ci sono un milione di altri casi da buttare via. (Un milione, Karl!)

Da qualche parte ho dimenticato di inizializzare una variabile o ho aggiunto un nuovo campo a una struttura che è diventata non inizializzata in tutto il programma, e il programma va avanti. Il programma funziona così e così...

Da qualche parte ho moltiplicato per 2 invece di 3, chiamato fn() invece di fn_(), ... . Se le tue mani sono sbagliate, sei nei guai.

Il linguaggio C è stato creato molto tempo fa quando le capacità dell'hardware erano molto scarse, ecco perché gran parte del lavoro di ottimizzazione è stato lasciato al programmatore. Se non vedi l'ora di farlo, perché ti riferisci al C e non all'Assembler? Codifica i sistemi di trading in Assembler. Sono sicuro che saranno i più veloci, forse anche in anticipo sul mercato.

per il vostro riferimento: standard C (gli ultimi, non sono standard C++): C11, C18, C2x è in preparazione. Piuttosto, hai scritto questo come risultato dell'incompetenza.
 
Vict:

Se il programma fosse completamente prevedibile in fase di compilazione, non avrebbe bisogno di essere eseguito in fase di esecuzione. Per definizione, deve prendere qualcosa dal mondo esterno e produrre un risultato basato su di esso, e questa è un'incertezza che ostacola l'ottimizzatore. Un altro segreto - le librerie condivise sono collegate con l'applicazione in runtime, l'ottimizzatore non può tracciare nulla lì. Ci sono un milione di altri casi da buttare via. Un milione, Karl).

Loscambio di dati con il mondo esterno sono casi speciali e richiedono soluzioni speciali. Stiamo parlando della programmazione in quanto tale e di quei casi in cui il compilatore ha la garanzia di sapere che la variabile non è controllata dall'esterno. E questo deve essere la stragrande maggioranza dei casi. Altrimenti si ha una programmazione puramente di sistema, che è davvero meglio fare in C, o ancora meglio - in assembler.

Da qualche parte moltiplicato per 2 invece di 3, chiamato fn() invece di fn_(), . . Se le tue mani sono storte, guai.

Se si moltiplica per 2 invece di 3, si ottiene un errore stabile nel programma che è facile da diagnosticare e trovare. E se la variabile non è inizializzata si ottiene qualcosa che ora funziona e poi no, di tanto in tanto, con conseguenze imprevedibili. In generale, è piuttosto strano che io vi spieghi queste basi, spacciandomi per un programmatore esperto.

 
Alexey Navoykov:

Scambio di dati con il mondo esterno - questi sono casi speciali, e richiedono soluzioni speciali. Ma stiamo parlando di programmazione in quanto tale, e di quei casi in cui il compilatore è garantito per sapere che la variabile non è controllata dall'esterno. E questo dovrebbe essere la stragrande maggioranza dei casi. Altrimenti, si ottiene una programmazione puramente di sistema, che è davvero meglio fare in C, o ancora meglio - in assembler.

La comunicazione con il mondo esterno è una parte essenziale di qualsiasi programma. Lasciatemi ripetere - altrimenti può essere capito in fase di compilazione. Per esempio, il compilatore taglierà l'inizializzazione qui?

int i = 54;
if (read_socket() == SIGNAL) {
   fn(i);
}
i = 100;
...

// естественно, что никто не пишет такой бред:
int q = 3;
q = 7;
q = 9;
fq(q);

Ovviamente, non ha idea di cosa restituirà read_socket(). Tutto il programma è "permeato" dall'interazione con il mondo esterno. + aggiungere una chiamata a moduli esterni qui... .

Se si moltiplica per 2 invece che per 3, si ottiene un errore stabile nel programma che è facile da diagnosticare e trovare. E con una variabile non inizializzata si ottiene qualcosa che funziona o meno di tanto in tanto, con conseguenze imprevedibili. In realtà è piuttosto strano che io spieghi queste basi a te che ti atteggi a programmatore esperto.

Guarda, se vuoi ottenere un errore stabile, è molto semplice inizializzare lo stack:

int main() {
    if (true)
        int init_stack[10000] {0};
}

Anche l'inizializzazione della memoria da HIP è un gioco da ragazzi. Se ci imbattiamo in qualche trappola di rappresentazione, otterremo un core dump a tutti.

Ancora una volta, se gli ottimizzatori fossero molto intelligenti, equiparerebbero default init a value init con inserimento di istruzioni di inizializzazione da parte del compilatore come necessario ancora in alcuni C11, ma ahimè. Nessuno obbliga, se non vuoi, fai T val{}; Stanco di spiegare cose elementari.

 
Vict:

Ancora una volta, se gli ottimizzatori fossero molto intelligenti, equiparerebbero default init a value init con il compilatore che inserisce istruzioni di inizializzazione come necessario in alcuni C11, ma ahimè. Nessuno obbliga, se non lo vuoi, fai T val{}; Stanco di spiegare cose elementari.

Perché, per come la vedo io, lo standard C++ descrive le regole in modo molto formale, senza contestualizzazione. Cioè si può sempre inizializzare o non inizializzare mai. Per confronto, in C# si può dichiarare una variabile senza inizializzazione, ma più avanti nel codice deve essere necessariamente inizializzata. Cioè, il compilatore analizza il codice che segue e non solo il comando corrente. Questo è previsto dalle regole del linguaggio, ma lo standard non prevede alcuna analisi in C++. Quindi, se forzano l'inizializzazione, vi lamenterete che voglio controllare e inizializzare tutto da solo! )

 
Alexey Navoykov:

Perché lo standard C++, per quanto ne so, descrive le regole in modo molto formale, senza contestualizzazione. Cioè o inizializzi sempre o non inizializzi mai. In confronto, in C# puoi dichiarare una variabile senza inizializzazione, ma più avanti nel codice deve essere necessariamente inizializzata. Cioè, il compilatore analizza il codice che segue e non solo il comando corrente. Questo è previsto dalle regole del linguaggio, ma lo standard non prevede alcuna analisi in C++. Quindi, se forzano l'inizializzazione, vi lamenterete che voglio controllare e inizializzare tutto da solo! )

È solo che le soluzioni collaudate ci arrivano e se funzionerà fuori dalla scatola, spesso causando inutili sovraccarichi, nessuno lo includerà. Per esempio, hanno scritto nello standard un MUST per il compilatore per fare l'elisione di copia in c++17.

 

L'argomento si chiama "Bug, bug, domande".

Per favore, create un topic dove discuterete di MQL vs C#, C++, e altre cose relative alla sintassi, compilatori e allenamenti mentali.

State disseminando il thread e le altre domande e i messaggi degli utenti stanno affogando nella vostra discussione.

Mi chiedono dove fare una domanda - sono diretto qui e la risposta è: "Gli zii stanno discutendo per un centinaio di pagine lì, quindi non interferirò, il resto non ha senso...

 
const int DEFAULT_INT_VALUE   = 147;
input int thisIsAnInput       = DEFAULT_INT_VALUE;
'NoConstForInput.mq5' NoConstForInput.mq5 1 1
'DEFAULT_INT_VALUE' - costante attesa NoConstForInput.mq5 13 33
1 errori, 0 avvertimenti 2 1

Edificio 2361 e 2390

 
Alain Verleyen:
'NoConstForInput.mq5' NoConstForInput.mq5 1 1
'DEFAULT_INT_VALUE' - costante attesa NoConstForInput.mq5 13 33
1 errori, 0 avvertimenti 2 1

Edificio 2361 e 2390

#define  DEFAULT_INT_VALUE 147
 
Vict:

Vedete, se volete ottenere un errore stabile, inizializzare lo stack è molto facile:

Anche l'inizializzazione della memoria da un HIP è un gioco da ragazzi. Se ci imbattiamo in qualche trappola di rappresentazione, otteniamo un core dump del tutto.

Un ultimo commento, per favore non arrabbiatevi con i moderatori )).

Ho bisogno di chiarire perché lo stack ha valori diversi da chiamata a chiamata. Si tratta di proteggere https://ru.wikipedia.org/wiki/ASLR, e non c'è nemmeno bisogno di inanalizzare nulla, come ho detto prima. Nel mio caso - eseguo il software sotto gdb (debugger), che lo posiziona allo stesso indirizzo ogni volta che viene eseguito, cioè lo stack non sarà contaminato da indirizzi di ritorno "casuali".