Un errore logico è sempre causato dalla riga di codice per il primo stato del programma che è sbagliato? [chiuso]

1

Un errore logico, contrariamente a un errore di runtime fatale, è un errore di runtime che non termina fatalmente un programma, ma fa qualcosa che non è inteso.

È un errore logico causato necessariamente dalla riga di codice per lo stato più iniziale che è sbagliato?

Oppure un errore logico può essere causato da una riga di codice prima della riga per il primo stato errato?

La mia domanda deriva principalmente da

  • Penso che il debug possa solo aiutare a capire se uno stato di un programma è giusto o sbagliato, e non oltre.

  • Credo che tramite il debug possiamo individuare la riga di codice che causa un errore logico, perché penso che un errore logico sia sempre causato dalla linea di codice per lo stato più iniziale che è sbagliato, non da una linea di codice che precede la riga di codice per lo stato meno recente che è errato.

Sbaglierò se fornisci un esempio di errore logico la cui causa non può essere trovata usando un debugger per tracciare gli stati del programma. In altre parole, puoi fornire un esempio di errore logico la cui causa è precedente ai primi stati del programma che è sbagliato?

    
posta Tim 30.10.2015 - 00:20
fonte

3 risposte

10

In base alla tua definizione, hai definito la tua risposta come vera.

Parli del primo "stato sbagliato". Cosa definisce uno stato sbagliato? Cosa lo rende sbagliato? In genere la risposta è "non era lo stato che era corretto". Per definizione, il primo stato errato è preceduto solo da stati corretti (o qualcosa è andato storto nel primo passo, ma inizia a essere un problema del sistema operativo). Quindi c'è una transizione da uno stato giusto a uno stato sbagliato.

Se si presume che l'unica cosa che può cambiare uno stato sia una dichiarazione (riga di codice), quindi per definizione l'affermazione che ha appena completato e portato al primo stato errato è "il problema".

Queste ipotesi non sono sempre valide. Ad esempio, è banale mostrare che se si utilizza un "memory trainer" che consente a un programma di inviare valori nello spazio di memoria di un altro programma, qualsiasi errore causato da questo trainer non è chiaramente causato da alcuna riga di codice!

Inoltre, è possibile avere casi in cui non esiste una linea che "causi" il problema. Uno di questi esempi è un caso di gara multithreading. In tal caso non è sempre possibile specificare quale thread ha "causato" il problema, perché il problema in realtà è originato dall'interazione tra due thread per causare uno "stato sbagliato". Poiché le istruzioni (righe di codice) vengono eseguite su un thread e l'errore non è "su un thread", nessuna riga di codice è in errore.

Un approccio più "costruttivo" potrebbe essere quello di cambiare la formulazione. Invece di parlare di "la linea che ha causato l'errore", pensa a "La linea che dovrebbe essere cambiata per correggere l'errore". Quella formulazione cambia le cose quel tanto che basta per evitare un gioco di colpa.

Questo è anche molto importante per gestire gli errori di memoria. Nel caso di questi bug, è spesso molto difficile identificare il primo vero "stato sbagliato", ma è facile identificare lo stato che segfaults. È facile presumere accidentalmente che l'errore debba essere una riga di codice vicino a dove è segfault perché si presume che il segfault sia il primo "stato errato" e si dimentichi di cercare l'effettiva causa principale.

    
risposta data 30.10.2015 - 02:09
fonte
7

Solo per confondere le cose, se elimini una linea essenziale di codice da un programma, allora funzionerà male.

Una volta fatto questo, l'errore logico nel codice non sarà in basso a nessuna linea nel programma. Sarà causato dall'assenza di una linea.

    
risposta data 30.10.2015 - 09:49
fonte
2

Considera questo: un algoritmo inadeguato o prematuro. Cioè, quando questo algoritmo viene eseguito, passerà attraverso solo un sottoinsieme degli stati validi, lasciando alcuni stati validi non visitati . In tal modo, perderà la risposta corretta; quindi, quando l'algoritmo finisce, finirà in uno stato (*) diverso dallo stato corretto.

(*) Considero il valore di ritorno da considerarsi parte dello stato.

Esempio: un algoritmo che cerca di cercare un particolare valore intero in un array intero.

L'algoritmo contiene un difetto, in modo tale da cercare solo gli elementi che si trovano su valori di indice pari. Gli articoli sui valori dell'indice dispari non vengono visitati.

La visita di elementi su indici pari comprende stati validi. Tuttavia, la mancanza di visitare elementi su indici dispari è un'omissione che porta a risultati errati.

L'errore logico si trova nello stato errato transizioni che lo fa saltare sugli indici.

Poiché un utente del debugger è in grado di eseguire l'esecuzione del programma, l'utente è in grado di visualizzare sia gli stati non corretti immessi, sia le transizioni di stato non corrette. Pertanto, l'errore sopra menzionato è raggiungibile utilizzando un debugger.

Tuttavia, per inadeguatezze algoritmiche non banali (usando un algoritmo inadeguato per l'attività), l'errore logico può essere visto solo da una persona che (1) sa quale algoritmo viene implementato nel codice e (2) ) sa che l'attuazione non sarà all'altezza dei requisiti del programma. Questo è il caso in cui "il debugging" avviene su carta, prima che qualsiasi riga di codice sia scritta.

    
risposta data 30.10.2015 - 10:26
fonte

Leggi altre domande sui tag