Bedingter Breakpoint: Dieser Ausdruck hat Nebenwirkungen und wird nicht ausgewertet

8

Ich habe eine nicht statische const-Methode namens size_t A::m() const , die ich verwenden möchte, um einen Haltepunkt auszulösen, wenn sie einen Wert größer als 1 zurückgibt. Hier ist class A und instance a :

%Vor%

Also füge ich einen Haltepunkt in Visual Studio 2013 mit dieser Bedingung

hinzu %Vor%

Wenn ich jedoch versuche, das zu kompilieren, bekomme ich die folgende Nachricht von der IDE:

  

Der folgende Haltepunkt kann nicht festgelegt werden:

     

Bei myFile.cpp, Zeile xxx, wenn 'a.m () & gt; 1 'ist wahr

     

Dieser Ausdruck hat Nebenwirkungen und wird nicht ausgewertet.

Beachten Sie, dass A::m() nichts ändert, sondern nur die Methode .size() eines Vektors aufruft und diesen Wert zurückgibt, so dass die Behauptung, dass der Ausdruck Nebenwirkungen hat, einfach falsch ist. In der Tat hat Ersetzen die Haltepunktbedingung mit a.myvec.size() > 1 (dh der Inhalt der Methode selbst) hat den gleichen Effekt!

Was als Bedingung in einem Haltepunkt verwendet werden kann, Microsoft sagt, dass ;

  

Die Bedingung kann ein beliebiger gültiger Ausdruck sein, der von der   Debugger.

Also ging ich und schaute Ausdrücke im Debugger und < a href="http://msdn.microsoft.com/en-us/library/vstudio/a7a250bs.aspx"> gefunden :

  

Eine häufige Ursache für Nebenwirkungen ist die Auswertung eines Funktionsaufrufs in a   Debugger-Fenster. Solche Bewertungen sind normalerweise bemerkbar. Ein mehr   Subtile Ursache für Nebenwirkungen ist die Bewertung von Eigenschaften und anderen   implizite Funktion ruft verwalteten Code auf.

     

Der Debugger kann nicht feststellen, ob eine Eigenschaftenbewertung oder implizit ist   Funktionsaufruf hat Nebenwirkungen. Daher standardmäßig der Debugger   Implizite Funktionsaufrufe werden nicht automatisch ausgewertet. Eigentum   Bewertung ist standardmäßig erlaubt, kann aber in den Optionen deaktiviert werden   Dialogbox. Wenn ein Funktionsaufruf oder eine Eigenschaft nicht ausgewertet wurde, a   Das Aktualisierungssymbol wird angezeigt. Sie können den Ausdruck manuell nach bewerten   Klicken Sie auf das Aktualisierungssymbol. Einzelheiten finden Sie unter Vorgehensweise: Aktualisieren der Überwachung   Werte.

     

Wenn die Auswertung von Eigenschaften oder impliziten Funktionsaufrufen aktiviert ist   Aus, Sie können die Auswertung erzwingen, indem Sie den AC-Format-Modifikator verwenden (für C #   nur). Siehe Formatspezifizierer in C #.

Wenn jemand den obigen Absatz ins Englische übersetzen könnte, wäre das großartig. Kann ich Funktionen in diese Debugger-Bedingungen einfügen oder nicht?

    
arman 04.11.2013, 23:01
quelle

4 Antworten

8

Hier ist meine Übersetzung des Hilfe-Links, den Sie zur Verfügung gestellt haben:

  • Absatz 1: Anruffunktionen haben wahrscheinlich Nebenwirkungen. Das Bewerten von Eigenschaften kann Nebenwirkungen haben.
  • Absatz 2: Der Debugger kann nicht erkennen, ob es Nebenwirkungen gibt, also nehmen wir einfach an: "functions = bad", "properties = good" (dh "Funktionen haben Nebenwirkung, Eigenschaften nicht") ). Aktualisieren Sie Symbolinformationen, die für das unmittelbare Problem nicht relevant sind.
  • Absatz 3: möchte den Debugger erzwingen? Wenn Sie C # verwenden, geben Sie ,ac nach Ihrer Auswertung ein.

Also, es läuft darauf hinaus, wenn Sie eine Funktion in Ihrer Auswertung aufrufen und C # verwenden möchten, fügen Sie ,ac danach hinzu

%Vor%

Da du C ++ verwendest, denke ich, dass dies auf "Keine Funktionen in deinen Evaluierungsanweisungen für dich" hinausläuft! Zum Zweck der Fehlersuche können Sie möglicherweise die Konstante const aus A::m entfernen, da der Spezifizierer keinen Einfluss auf den Logikfluss hat (sollte). Ich bin mir nicht einmal sicher, ob das funktioniert.

    
Scott Mermelstein 04.11.2013, 23:20
quelle
8

Das Auswerten eines Funktionsaufrufs hat Nebenwirkungen, weil er eine Zustandsänderung entweder in Registern oder im Stapel oder in beiden auslöst. Das ist genau das, was der letzte von Ihnen zitierte Absatz sagt.

In Ihrem Fall werden sowohl die Register als auch der Stapel unter der Annahme von Standard-Projekteinstellungen geändert. Eine Anweisung call wird verwendet, um m() aufzurufen, wodurch der Befehlszeiger auf den Stapel geschoben wird und der Rückgabewert in eax gespeichert wird. Zusätzlich zu diesen beiden offensichtlichen Nebenwirkungen werden Stack und Register auch durch den Prolog / Epilog geändert, der für die Aufrufkonvention von m generiert wurde.

Dies kann verifiziert werden, indem eine nackte Funktion erzeugt wird und Inline-Assembler verwendet wird, der nur die Register ändert:

%Vor%

Wenn Sie zu irgendeinem Zeitpunkt in dieser Anwendung den Debugger mit foo() in Ihrer Beobachtungsliste unterbrechen, wird 'Dieser Ausdruck hat Nebenwirkungen und wird nicht ausgewertet' angezeigt.

    
Collin Dauphinee 05.11.2013 00:30
quelle
1

Hier im Dunkeln geschossen, aber vielleicht möchten Sie die Verwendung von const in Ihrer Methodendeklaration genauer betrachten. Vielleicht möchten Sie explizit angeben, was nicht in ein const geändert werden soll (IIRC korrekt const kann an fünf verschiedenen Stellen in einer Methodendeklaration verwendet werden, also schauen Sie genau hin).

const ist ein Vertrag, den der Compiler erzwingt. Wenn Ihre Methode auf einen Zeiger zugreift, der nicht const ist, könnte dies ein Problem sein. Wenn es eine statische Variable gibt, könnte das ein Problem sein. Es ist auch möglich, dass, während Ihr Compiler vielleicht froh ist, dass const in Ihrem Code in Ordnung ist, die IDE möglicherweise nicht so intelligent wie der Compiler ist (und daher vielleicht noch mehr const assurance haben möchte).

Ohne deinen Code ist es schwer zu sagen, aber das sollte dir zumindest eine Idee geben.

Für etwas mehr lesen auf const scheint diese Seite ein anständiges Tutorial zu haben:

Ссылка

    
Dan L 04.11.2013 23:10
quelle
1

Es gibt gute Antworten, die die Aussage übersetzen, aber hier ist ein netter Hack, den jemand benutzen könnte.

Fügen Sie in Ihrem Code, an dem Sie einen Unterbrechungspunkt hinzufügen möchten, eine Zeile wie

hinzu %Vor%

Legen Sie dort einen Haltepunkt fest, und Sie können dies in der Bedingung hinzufügen

%Vor%

Oder Sie könnten so etwas tun

%Vor%

und kann einen Breakpoint in der Debug-Zeile setzen.

    
Existent 26.08.2016 17:58
quelle