Frage

Damit meine ich, was muss ich nützlich Behauptungen in meinem Code tun?

MFC ganz einfach ist, verwende ich nur ASSERT (etwas).

Was ist der Nicht-MFC Weg?

Edit:? Ist es möglich, in assert.c zu stoppen behaupten zu brechen, anstatt als meine Datei, die assert genannt ()

Edit:? Was ist der Unterschied zwischen <assert.h> & <cassert>

akzeptierte Antwort: viele interessante Antworten in diesem Beitrag, ich wünschte, ich mehr als eine Antwort akzeptieren konnte (oder jemand würde sie alle kombinieren). So bekommt Antwort vergeben Ferruccio (für die erste Antwort).

War es hilfreich?

Lösung

#include <cassert>

assert(something);

und zur Kompilierung-Überprüfung, Boost-statische behauptet sind ziemlich nützlich:

#include <boost/static_assert.hpp>

BOOST_STATIC_ASSERT(sizeof(int) == 4);  // compile fails if ints aren't 32-bit

Andere Tipps

Es hängt davon ab, ob Sie nach etwas suchen, der außerhalb von Visual C ++ funktioniert. Es hängt auch davon ab, welche Art von Behauptung Sie suchen.

Es gibt einige Arten von Behauptungen:

  1. Preprocessor
    Diese Behauptungen sind fertig mit der Präprozessordirektive #error
    Preprocessor Behauptungen werden nur während der Vorlaufphase ausgewertet und sind daher nicht nützlich für Dinge wie Vorlagen.

  2. Ausführen Zeit
    mit der assert() Funktion in <cassert>
    definiert Diese Behauptungen sind fertig Execute Zeit Behauptungen sind nur zur Laufzeit ausgewertet. Und wie BoltBait wies darauf hin, sind nicht, wenn der NDEBUG Makro definiert wurde zusammengestellt aus.

  3. Static
    Diese Behauptungen sind fertig, wie Sie gesagt haben, durch die ASSERT() Makro verwenden, aber nur, wenn Sie mit MFC. Ich weiß nicht, von einer anderen Weise statische Behauptungen zu tun, dass ein Teil der C / C ++ Standard jedoch ist, bietet die Boost-Bibliothek eine andere Lösung. static_assert
    Die static_assert Funktion aus der Boost-Bibliothek ist etwas, das in der C ++ 0x-Standard .

Als zusätzliche Warnung, die assert() Funktion, die Ferruccio vorgeschlagen nicht das gleiche Verhalten wie das MFC ASSERT() Makro hat. Ersteres ist eine Zeit Behauptung ausführen, während die später eine statische Behauptung ist.

Ich hoffe, das hilft!

Assert ist (in der Regel) Debug Nur

Das Problem mit „behauptet“ ist, dass es in der Regel in Debugbinärdateien ist, und dass einige Entwickler verwenden sie, als ob der Code in der Produktion noch sein würde.

Das ist nicht böse per se, da der Code soll intensiv getestet werden und damit die Fehler der assert produzieren wird sicher entdeckt werden, und entfernt werden.

Aber manchmal (die meisten der Zeit?), Sind die Tests nicht so intensiv wie gewünscht. Ich werde nicht über einen alten Job spricht, wo wir bis zur letzten Minute codieren hatten ( Sie fragt nicht ... Manchmal Manager sind nur ... Ähem ... ) ... Was ist der Sinn einer Assertion Sie einen Code hinzufügen, die in der nächsten Minute an den Client als Veröffentlichungs Binary kompiliert und geliefert werden?

Assert in (etwas) realen Anwendungen

In unserem Team, wir brauchten etwas, um den Fehler zu erkennen und zugleich etwas anderes den Fehler zu behandeln. Und wir brauchten es möglicherweise auch auf Releasebuild.

Assert werden beide erkennen und den Fehler behandeln nur auf Debug-Build.

So haben wir stattdessen eine XXX_ASSERT Makro, sowie einen XXX_RAISE_ERROR Makro.

Das XXX_ASSERT Makro würde das gleiche wie der ASSERT-Makro tun, aber es wäre sowohl in Debug und Release gebaut werden. Sein Verhalten (schreibt ein Protokoll, eine messagebox öffnen, nichts tun, etc.) durch eine INI-Datei gesteuert werden kann, und dann wäre es Abbruch / Beenden der Anwendung.

Dies wurde verwendet, wie:

bool doSomething(MyObject * p)
{
   // If p is NULL, then the app will abort/exit
   XXX_ASSERT((p != NULL), "Hey ! p is NULL !") ;

   // etc.
}

XXX_RAISE_ERROR Makro würde nur „log“ den Fehler aber würde nicht versuchen, es zu handhaben. Dies bedeutet, dass er die Nachricht in einer Datei protokolliert werden könnten und / oder eine MessageBox mit der Nachricht öffnen und eine Taste, um fortzufahren, und eine andere eine Debug-Sitzung zu starten (per INI-Datei config). Dies wurde als:

bool doSomething(MyObject * p)
{
   if(p == NULL)
   {
      // First, XXX_RAISE_ERROR will alert the user as configured in the INI file
      // perhaps even offering to open a debug session
      XXX_RAISE_ERROR("Hey ! p is NULL !") ;
      // here, you can handle the error as you wish
      // Than means allocating p, or throwing an exception, or
      // returning false, etc.
      // Whereas the XXX_ASSERT could simply crash.
   }

   // etc.
}

Ein Jahr nach ihrer Einführung in unseren Libs, nur XXX_RAISE_ERROR verwendet wird. Natürlich kann es nicht auf zeitkritische Teile der App verwendet werden (wir haben eine XXX_RAISE_ERROR_DBG dafür), aber überall sonst, ist es gut. Und die Tatsachen, die man auch immer bevorzugte Fehlerbehandlung verwenden kann, und dass es nach Belieben aktiviert werden kann, entweder auf dem Entwickler-Computer oder den Tester oder auch den Benutzer, sind sehr nützlich.

Um die Frage in Ihrem zweiten "bearbeiten" zu beantworten:

ist der C-Header

ist der C ++ Standard Library Header ... es enthält typischerweise

in der Datei zu brechen, der die Assertion genannt, können Sie eine benutzerdefinierte Makro verwenden, die eine Ausnahme oder rufen __debugbreak wirft:

#define MYASSERT(EXPR, MSG) if (!(EXPR)) throw MSG;

Oder:

#define MYASSERT(EXPR) if (!(EXPR)) __debugbreak();

Grund Assert Verbrauch

#include <cassert>

/* Some code later */
assert( true );

Best Practice Hinweise

ASSERTS werden verwendet, um zu identifizieren Runtime-Zustände, die wahr sein sollte . Als Ergebnis, werden sie im Release-Modus kompiliert werden.

Wenn Sie eine Situation, wo Sie eine Assertion zu wollen immer getroffen, können Sie falsch es passieren. Zum Beispiel:

switch ( someVal ):
{
case 0:
case 1:
  break;
default:
  assert( false ); /* should never happen */
}

Es ist auch möglich, eine Nachricht durch assert weitergeben müssen:

assert( !"This assert will always hit." );

Ältere Codebases häufig die Assertion-Funktionalität erweitern. Einige der gemeinsamen Erweiterungen gehören:

  • Makeln behauptet auf einer Pro-Modul Basis-Tests zu lokalisieren.
  • Erstellen eines zusätzlichen assert-Makro, das in kompilierten geführt meisten Debug-Builds. Dies ist wünschenswert, für Code, der sehr häufig genannt wird (Millionen Mal pro Sekunde) und ist unwahrscheinlich, falsch sein.
  • Benutzer ermöglichen, die derzeit getroffen assert zu deaktivieren, aktivieren alle in der Übersetzungseinheit oder alle behaupten, in der Codebasis. Dadurch wird verhindert, gutartige behauptet von ausgelöst wird, wodurch unbrauchbar baut.

Microsoft-spezifische CRT behauptet

#include <crtdbg.h>
#include <sstream>
...
// displays nondescript message box when x <= 42
_ASSERT(x > 42);
// displays message box with "x > 42" message when x <= 42
_ASSERTE(x > 42);
// displays message box with computed message "x is ...!" when x <= 42
_ASSERT_EXPR(
   x > 42, (std::stringstream() << L"x is " << x << L"!").str().c_str());

Es ist eine erweiterte Open-Source-Bibliothek namens ModAssert, die Behauptungen hat, die sowohl Visual C ++ und gcc arbeiten. Wahrscheinlich auch auf anderen Compilern, weiß nicht sicher. Es dauert einige Zeit, es zu lernen, aber wenn man gute Behauptungen mag, die auf MFC nicht abhängen, auf diese aussieht. Es ist unter http://sourceforge.net/projects/modassert/

Verwendung intellisense es in Visual Studio (rechte Maustaste) zu öffnen

// cassert standard header
#include <yvals.h>
#include <assert.h>

yvals.h ist Windows Zeug. so, soweit assert () selbst betrifft, sind die beiden Möglichkeiten, umfassen sie identisch sind. es ist eine gute Übung, die <cxxx> zu verwenden, weil es oft nicht so einfach ist (Namespace-Verpackung und vielleicht andere Magie)

Dies bricht bei Anrufer-Website für mich ...

hier ist ein Artikel rel="nofollow zu erklären, warum Sie nicht wollen, dieses Makro selbst schreiben.

Hier ist meine neueste Iteration einer Assertion Anlage in C ++: http://pempek.net/articles/2013/11/17/cross-platform-cpp-assertion-library/

Es ist eine Drop-in-2-Dateien lib Sie einfach zu Ihrem Projekt hinzufügen kann.

Um die Fragesteller hat die dritte Frage zu beantworten: der erste Grund, warum wir „cassert“ statt „assert.h“ ist, weil im Fall von C ++ gibt es eine Zulage aus der Tatsache, dass der C ++ Compiler verwenden, um die Funktionsbeschreibungen in Code-Dateien nicht speichern, sondern in einer DLL oder im Compiler selbst. Die zweite ist, dass es kleinere Änderungen an Funktionen gemacht, um sein kann, die Unterschiede zwischen C und C ++, entweder vorhanden oder in Zukunft zu erleichtern. Da assert.h eine C-Bibliothek, ist der Vorzug zu verwenden "cassert", während in C ++.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top