2015-02-06 23 views
16

Questo è molto pericoloso, quindi mi chiedo perché è permesso. Dal momento che ho spesso bisogno di passare da VB.NET e C# a volte aggiungo breakpoint-condizioni come segue:Perché la condizione del punto di interruzione del debugger consente un'istruzione di assegnazione come condizione di bool?

foo = "bah" 

Voglio smettere se la variabile stringfoo è "bah, quindi il modo corretto era di usare al posto di foo == "bah"foo = "bah".

Ma "funziona". Non si ricevono avvisi o errori in fase di compilazione o di runtime. Ma in realtà questo modifica la variabile foo, lo rende sempre "bah" anche se aveva un valore diverso. Poiché ciò accade silenziosamente (il punto di interruzione non viene mai colpito) è incredibilmente pericoloso.

Perché è consentito? Dov'è il mio errore nel ragionamento (a parte confondere la sintassi C# e VB.NET)? In C# (a differenza di VB.NET) un assignment statement restituisce il valore assegnato, quindi non un bool, ma un string in questo caso. Ma una condizione di punto di interruzione deve essere un bool se si seleziona la casella "È vero".

Ecco un piccolo "programma" del campione e screenshot dal mio (tedesco) IDE:

static void Main() 
{ 
    string foo = "foo"; 
    // breakpoint with assignment(foo = "bah") instead of comparison(foo == "bah"): 
    Console.WriteLine(foo); // bah, variable is changed from the breakpoint window 
} 

la finestra di breakpoint-condizione:

enter image description here

Il codice come immagine compreso il punto di interruzione :

enter image description here

+1

Bella domanda. Questo suona decisamente come un insetto. –

+0

Sicuramente non sembra corrispondere alla [documentazione] (https://msdn.microsoft.com/query/dev12.query?appId=Dev12IDEF1&l=EN-US&k=k (vs.debug.breakpt.condition); k (TargetFrameworkMoniker-.NETFramework, Version% 3Dv4.5); k (DevLang-csharp) & rd = true): "Il punto di interruzione viene saltato solo se la condizione è valida e restituisce false" –

+0

@Damien_The_Unbeliever: sì, in fase di esecuzione il debugger normalmente si ferma al punto di interruzione se non è valido e lo segnala. Ma non nel caso di un incarico. Puoi riprodurlo? –

risposta

7

È una conseguenza automatica della sintassi C#, comune nel gruppo di lingue delle parentesi graffe. Un incarico è anche un'espressione, il suo risultato è il valore dell'operando di destra. Il debugger non si oppone né alle espressioni che hanno effetti collaterali, né sarebbe semplice sopprimerle. Potrebbe essere incolpato di non controllare che l'espressione abbia un risultato bool, tuttavia il debugger non ha un parser in linguaggio C# completo. Questo potrebbe essere risolto in VS2015 grazie al progetto Roslyn. [Nota: vedi addendum in basso].

Anche il motivo principale per cui i linguaggi di parentesi graffa richiedono un operatore separato per l'uguaglianza, == vs =. Che di per sé deve essere responsabile di miliardi di dollari di bug, ogni programmatore C commette questo errore almeno una volta.

VB.NET è diverso, l'assegnazione è una dichiarazione e il token = è valido sia per l'assegnazione che per il confronto. Puoi dirlo dal debugger, invece seleziona l'operatore di uguaglianza e non modifica la variabile.

Tieni presente che questo è effettivamente utile. Ti consente di aggirare temporaneamente un bug, forzare il valore della variabile e permetterti di continuare il debug e concentrarti su un altro problema. O creare una condizione di test. È abbastanza utile. In una vita precedente, ho scritto un compilatore e un debugger e ho implementato "trace points". Scoperto per caso lo stesso scenario e lasciato in posizione. Funzionava in un host che si basava molto sulle macchine a stati, ignorando la variabile di stato mentre il debugging era incredibilmente utile.L'incidente, no, non così utile :)


Una nota su ciò che gli altri così gli utenti stanno osservando, dipende dal motore di debug che si utilizza. L'opzione rilevante in VS2013 è Strumenti + Opzioni, Debug, Generale, "Usa modalità di compatibilità gestita". La stessa opzione esiste in VS2012, aveva un nome leggermente diverso (non ricordo). Quando spuntato, si ottiene un motore di debug più vecchio, uno ancora compatibile con C++/CLI. Lo stesso usato in VS2010.

Quindi questa è una soluzione alternativa per VS2013, deselezionare l'opzione per ottenere che il debugger verifichi che l'espressione produca un risultato bool. Ottieni un po 'più chic con quel nuovo motore di debug, come vedere i valori restituiti dal metodo e il supporto Modifica + Continua per i processi a 64 bit.

+1

"Questo potrebbe essere risolto in VS2015" - è stato risolto in VS2013 secondo i commenti – Rawling

+0

Grazie. Ma come Damien_The_Unbeliever [ha sottolineato] (http://stackoverflow.com/questions/28366325/why-does-the-debuggers-breakpoint-condition-allow-an-assignment-statement-as-bo/28368611#comment45074312_28366325) in il suo commento sembra essere già stato risolto in VS 2013, non è vero? –

+0

Ok, ho trovato il motivo, post aggiornato. –

1

Non posso essere d'accordo sulla natura bug di questo comportamento. Pochi esempi in cui per scopi di debug nella mia vita se fosse utile:
1. Altri thread modifica qualcosa nel codice.
2. Altre servizio valore aggiornato in dB
quindi suppongo che per i casi di sincronizzazione può essere caratteristica utile, ma sono d'accordo che può causare problemi

+1

Ma perché una finestra delle condizioni di breakpoint dovrebbe essere responsabile della modifica delle variabili? Il suo unico scopo è definire la condizione del punto di interruzione e non modificare il mio programma. È possibile utilizzare le altre finestre del debugger come la finestra di controllo rapido per modificare le variabili. Quindi, anche se è stato utile per te (e Hans Passant), è una grande fonte di pericolo di cambiamenti accidentali che non saranno riconosciuti. –

+1

D'accordo con te. Ho appena proposto qualcosa che chiamo utilizzo di bug –

Problemi correlati