Sdílet prostřednictvím


Tvrzení

Prohlášení o uplatnění Určuje podmínku, která očekáváte, že platit v okamžiku ve vašem programu.Pokud je tato podmínka není splněna, kontrolní výraz selže, dojde k přerušení programu a Chyba při vyhodnocení dialogové se zobrazí.

Visual C++ podporuje kontrolní výraz příkazy, které jsou založeny na následující konstrukce:

  • Kontrolní výrazy knihovny MFC pro aplikace knihovny MFC.

  • ATLASSERT programů, které používají knihovnu ATL.

  • CRT výrazy pro programy, které používají knihovny běhu jazyka C.

  • ANSI vyhodnocení funkce pro ostatní programy C/C++.

Výrazy můžete použít k zachycení chyb logiky, zkontrolovat výsledky operace a testování chybových stavů, které by byly zpracovány.

V tomto tématu

Jak fungují výrazy

Kontrolní výrazy v sestavení ladění a vydání

Vedlejší účinky používání výrazy

Kontrolní výrazy CRT

Kontrolní výrazy knihovny MFC

  • Knihovna MFC ASSERT_VALID a CObject::AssertValid

  • Omezení AssertValid

Používat výrazy

  • Zachycení chyb logiky

  • Kontrola výsledků

  • Zjištění neošetřené chyby

Jak fungují výrazy

Pokud ladicí program zastaví z důvodu nepravdivých běhové knihovny MFC nebo C, pak v případě, že zdroj je k dispozici, ladicí program přejde na bod ve zdrojovém souboru, kde došlo k kontrolní výraz.Výraz zobrazí v obou okno výstup a Chyba při vyhodnocení dialogové okno.Můžete zkopírovat zprávu kontrolní výraz z výstup okna do okna text, pokud chcete uložit pro pozdější použití.Výstup okno může obsahovat další chybové zprávy.Tyto zprávy zkontrolujte pečlivě, protože poskytují záchytné body příčině nezdaru při.

Použijte kontrolní výrazy ke zjišťování chyb během vývoje.Jako pravidlo použijte jeden výraz pro každý předpoklad.Je-li předpokládat, že argument není NULL, operátor nepravdivých testování tohoto předpokladu.

V tomto tématu

Kontrolní výrazy v sestavení ladění a vydání

Příkazy kontrolní výraz zkompiluje pouze v případě, _DEBUG je definován.V opačném případě kompilátor považovány výrazy null příkazy.Proto výraz příkazy Uložit bez režie nebo výkonu nákladů v konečné verzi programu a umožňují vyhnout se použití #ifdef směrnic.

Vedlejší účinky používání výrazy

Přidáte-li výrazy do vašeho kódu, ujistěte se, že kontrolní výrazy nemají vedlejší účinky.Zvažte například následující výraz, který upravuje nM hodnotu:

ASSERT(nM++ > 0); // Don't do this!

Protože ASSERT výrazu není vyhodnocena ve verzi programu, nM v Debug a Release verze budou mít různé hodnoty.Chcete-li se vyhnout tomuto problému v knihovně MFC, můžete ověřit makra namísto ASSERT.VERIFYvyhodnotí výraz ve všech verzích, ale nekontroluje výsledkem vydané verze.

Buďte obzvlášť opatrní o použití volání funkce ve výrazu příkazy, protože vyhodnocení funkce může mít neočekávané vedlejší účinky.

ASSERT ( myFnctn(0)==1 ) // unsafe if myFnctn has side effects
VERIFY ( myFnctn(0)==1 ) // safe

VERIFYvolání myFnctn jak Debug a Release verze, tak je přijatelné použít.Avšak pomocí VERIFY ukládá režii volání nepotřebné funkce ve verzi vydání.

V tomto tématu

Kontrolní výrazy CRT

CRTDBG.Definuje soubor hlaviček H makra _ASSERT a _ASSERTE pro kontrolu výrazu.

Makro

Výsledek

_ASSERT

Je-li zadaný výraz je vyhodnocen jako NEPRAVDA, název a řádek číslo _ASSERT.

_ASSERTE

Stejné jako _ASSERT, plus řetězcové reprezentace výrazu, která byla uplatněna.

_ASSERTEje výhodnější, protože hlásí uplatňovaného výraz, který je FALSE.To může stačit k identifikaci problému bez vztahu ke zdrojovému kódu.Ladicí verze aplikace bude však obsahovat řetězcová konstanta pro každý výraz uplatněna pomocí _ASSERTE.Používáte-li mnoho _ASSERTE makra, tyto výrazy řetězec zabírat značné množství paměti.Pokud je to, že se jedná o problém, použijte _ASSERT k úspoře paměti.

Při _DEBUG je definován _ASSERTE makro je definováno takto:

#define _ASSERTE(expr) \
   do { \
      if (!(expr) && (1 == _CrtDbgReport( \
         _CRT_ASSERT, __FILE__, __LINE__, #expr))) \
         _CrtDbgBreak(); \
   } while (0)

Pokud uplatňovaného výraz vyhodnocen jako NEPRAVDA, _CrtDbgReport se nazývá hlášení selhání výrazu (pomocí dialogového okna zprávy ve výchozím nastavení).Pokud se rozhodnete Opakovat v dialogovém okně zprávy _CrtDbgReport vrátí hodnotu 1 a _CrtDbgBreak volání ladicího programu prostřednictvím DebugBreak.

ww5t02fa.collapse_all(cs-cz,VS.110).gifKontrola poškození haldy

Následující příklad používá _CrtCheckMemory Kontrola poškození haldy:

_ASSERTE(_CrtCheckMemory());

ww5t02fa.collapse_all(cs-cz,VS.110).gifKontrola platnosti ukazatele

Následující příklad používá _CrtIsValidPointer Chcete-li ověřit, platí rozsah dané paměti pro čtení nebo zápis.

_ASSERTE(_CrtIsValidPointer( address, size, TRUE );

Následující příklad používá _CrtIsValidHeapPointer Chcete-li ověřit ukazatel odkazuje na paměť haldy pro místní (haldy a spravovány touto instancí běhové knihovny C – knihovna DLL může mít svůj vlastní instance knihovny, a proto vlastní haldy mimo haldy aplikace).Toto tvrzení zachytí nikoli pouze hodnotu null nebo out-of-bounds adresy, ale také odkazy na statické proměnné, proměnné zásobníku a jiné místní paměti.

_ASSERTE(_CrtIsValidPointer( myData );

ww5t02fa.collapse_all(cs-cz,VS.110).gifKontrola paměti bloku

Následující příklad používá _CrtIsMemoryBlock Chcete-li ověřit, že blok paměti je místní haldy a má platný blok typu.

_ASSERTE(_CrtIsMemoryBlock (myData, size, &requestNumber, &filename, &linenumber));

V tomto tématu

Kontrolní výrazy knihovny MFC

Knihovna MFC definuje ASSERT makro pro kontrolu výrazu.Definuje také MFC ASSERT_VALID a CObject::AssertValid metody pro kontrolu vnitřní stav CObject-odvozeného objektu.

Pokud argument knihovny MFC ASSERT makro vyhodnocen jako nula nebo hodnotu false, makro zastaví provádění programu a upozorní uživatele; v opačném případě pokračuje.

Když nepravdivých selže, dialogové okno se zprávou se zobrazí název zdrojový soubor a číslo řádku výraz.Pokud tlačítko Opakovat v dialogovém okně pole, volání AfxDebugBreak způsobí spuštění ke vstupu do ladicího programu.V daném okamžiku můžete prozkoumat zásobníku volání a použít jiné zařízení pro ladicí program zjistit, proč prosazení se nezdařilo.Pokud jste povolili ladění Just in timea nebyla již spuštěn ladicí program, dialogového okna spustit ladicí program.

Následující příklad ukazuje, jak používat ASSERT Chcete-li zkontrolovat vrácenou hodnotu funkce:

int x = SomeFunc(y);
ASSERT(x >= 0);   //  Assertion fails if x is negative

Můžete použít ASSERT se IsKindOf funkci pro kontrolu argumentů funkce:

ASSERT( pObject1->IsKindOf( RUNTIME_CLASS( CPerson ) ) );

ASSERT Makra vytváří žádný kód v prodejní verze.Vyhodnocení výrazu v prodejní verze, použijte ověřit makra namísto ASSERT.

ww5t02fa.collapse_all(cs-cz,VS.110).gifKnihovna MFC ASSERT_VALID a CObject::AssertValid

CObject::AssertValid metoda umožňuje spuštění kontroly vnitřní stav objektu.Přestože není nutné přepsat AssertValid při odvození vaší třídy z CObject, můžete provést vaší třídy spolehlivější tímto způsobem.AssertValidby měly být provedeny kontrolní výrazy všechny členské proměnné objektu, chcete-li ověřit, zda obsahují platné hodnoty.Například by měla zkontrolovat, že ukazatel členské proměnné nejsou NULL.

Následující příklad ukazuje, jak deklarovat AssertValid funkce:

class CPerson : public CObject
{
protected:
    CString m_strName;
    float   m_salary;
public:
#ifdef _DEBUG
    // Override
    virtual void AssertValid() const;
#endif
    // ...
};

Při přepsání AssertValid, volat verze základní třídy AssertValid před provedením vlastní kontroly.Poté použijte makro ASSERT zkontrolovat členy, které jsou jedinečné pro odvozenou třídu, jak je znázorněno zde:

#ifdef _DEBUG
void CPerson::AssertValid() const
{
    // Call inherited AssertValid first.
    CObject::AssertValid();

    // Check CPerson members...
    // Must have a name.
    ASSERT( !m_strName.IsEmpty());
    // Must have an income.
    ASSERT( m_salary > 0 );
}
#endif

Pokud všechny členské proměnné ukládat objekty, můžete použít ASSERT_VALID makro k testování jejich vnitřní platnost (je-li přepsat jejich třídy AssertValid).

Zvažte například třídu CMyData, které obchody CObList v jednom z jeho členské proměnné.CObList Proměnné, m_DataList, ukládá kolekci CPerson objekty.Zkrácený prohlášení o CMyData vypadá podobně jako tento:

class CMyData : public CObject
{
    // Constructor and other members ...
    protected:
        CObList* m_pDataList;
    // Other declarations ...
    public:
#ifdef _DEBUG
        // Override:
        virtual void AssertValid( ) const;
#endif
    // And so on ...
};

AssertValid Přepsat v CMyData vypadá podobně jako tento:

#ifdef _DEBUG
void CMyData::AssertValid( ) const
{
    // Call inherited AssertValid.
    CObject::AssertValid( );
    // Check validity of CMyData members.
    ASSERT_VALID( m_pDataList );
    // ...
}
#endif

CMyDatapoužívá AssertValid mechanismus testovat platnost objekty uložené v jeho datový člen.Přepsání AssertValid z CMyData vyvolá ASSERT_VALID makro pro své vlastní členskou proměnnou m_pDataList.

Testování platnosti nezastaví na této úrovni protože třída CObList také přepisuje AssertValid.Toto přepsání provede další platnosti testování na vnitřní stav ze seznamu.Tedy platnost na test CMyData objektu vede k další platnosti zkoušky pro interní stavy uložené CObList objekt seznamu.

Některé další práci, můžete přidat platnosti zkoušky CPerson objekty, které jsou také uloženy v seznamu.Mohl by odvozovat třídu CPersonList z CObList a přepsat AssertValid.V přepsané, volání CObject::AssertValid a potom iterovat v seznamu volání AssertValid na každém CPerson objektu, které jsou uloženy v seznamu.CPerson Třídy, které jsou uvedeny na začátku tohoto tématu již má přednost před AssertValid.

Jedná se o účinný mechanismus, při sestavení pro ladění.Následně, před vytvořením propuštění mechanismus je automaticky vypnuta.

ww5t02fa.collapse_all(cs-cz,VS.110).gifOmezení AssertValid

Vyžádané kontrolní výraz označuje, že objekt je jednoznačně chybné a spuštění zastaví.Však chybějící výraz označuje pouze nebyly zjištěny žádné problémy, že objekt není zaručena dobré.

V tomto tématu

Používat výrazy

ww5t02fa.collapse_all(cs-cz,VS.110).gifZachycení chyb logiky

Kontrolní výrazy můžete nastavit podmínky, že musí být splněny podle logiky aplikace.Výraz nemá žádný vliv, pokud dojde k chybě logiku.

Předpokládejme například, jsou simulace molekul plynu v kontejneru a proměnnou numMols představuje celkový počet molekul.Toto číslo nesmí být menší než nula, tak může zahrnovat příkazu knihovny MFC výrazu následujícím způsobem:

ASSERT(numMols >= 0);

Nebo může obsahovat výraz CRT následujícím způsobem:

_ASSERT(numMols >= 0);

Tyto příkazy Neprovádět žádnou akci, je-li váš program pracuje správně.Pokud logická chyba způsobí, že numMols Chcete-li být menší než nula, ale výraz zastaví provádění programu a zobrazí Chyba při vyhodnocení dialogové okno.

V tomto tématu

ww5t02fa.collapse_all(cs-cz,VS.110).gifKontrola výsledků

Výrazy jsou důležité pro testování operací, jejichž výsledky jsou zřejmé z rychlý vizuální kontrole.

Zvažte například následující kód, který aktualizuje proměnnou iMols na základě obsahu propojeného seznamu odkazuje mols:

/* This code assumes that type has overloaded the != operator
 with const char * 
It also assumes that H2O is somewhere in that linked list. 
Otherwise we'll get an access violation... */
while (mols->type != "H2O")
{
 iMols += mols->num;
 mols = mols->next;
}
ASSERT(iMols<=numMols); // MFC version
_ASSERT(iMols<=numMols); // CRT version

Počet molekul počítá podle iMols musí být vždy menší než celkový počet molekul, numMols.Vizuální prohlídka smyčky nezobrazuje, že to nutně bude v případě, takže příkazu kontrolní výraz se používá po smyčce k testování pro tuto podmínku.

V tomto tématu

ww5t02fa.collapse_all(cs-cz,VS.110).gifZjištění neošetřené chyby

Použít kontrolní výrazy pro testování chybových podmínek na místě ve vašem kódu kde všechny chyby by měly být manipulováno.V následujícím příkladu grafické rutiny vrátí kód chyby nebo nula pro úspěch.

myErr = myGraphRoutine(a, b);

/* Code to handle errors and
   reset myErr if successful */

ASSERT(!myErr); -- MFC version
_ASSERT(!myErr); -- CRT version

Je-li kód pro zpracování chyb funguje správně, by měly být zpracovány chyby a myErr obnovit nula ještě před dosažením výraz.Pokud myErr má jinou hodnotou, kontrolní výraz selže, program zdržovalo a Chyba při vyhodnocení dialogové okno se zobrazí.

Kontrolní výraz příkazy nejsou však nenahrazuje kód pro zpracování chyb.Následující příklad ukazuje výraz příkazu, který může vést k problémům v konečné verzi kódu:

myErr = myGraphRoutine(a, b);

/* No Code to handle errors */

ASSERT(!myErr); // Don't do this!
_ASSERT(!myErr); // Don't do this, either!

Tento kód se opírá o uplatnění prohlášení zpracování chybového stavu.V důsledku toho jakýkoli kód chyby vrácený myGraphRoutine bude ošetřena v konečné verzi kódu.

V tomto tématu

Viz také

Referenční dokumentace

Výrazy ve spravovaném kódu

Koncepty

Zabezpečení Debugger

Další zdroje

Ladění nativního kódu