Wat is het verschil tussen assert en static_asset?

Ik weet dat static_assertbeweringen doet tijdens het compileren, en assert– tijdens runtime, maar wat is het verschil in de praktijk? Voor zover ik begrijp, zijn het diep van binnen stukjes code, zoals

if (condition == false) exit();
  • Kan iemand me een voorbeeld geven van waar alleenstatic_assertzal werken, of alleenassert?
  • Doen ze iets wat een simpele if-instructie niet kan doen?
  • Is het een slechte gewoonte om ze te gebruiken?

Antwoord 1, autoriteit 100%

Je stelt drie vragen, dus ik zal proberen ze allemaal te beantwoorden.

  • Kan iemand me een voorbeeld geven van waar alleenstatic_assertzal werken, of alleenassert?

static_assertis goed voor het testen van logica in je code tijdens het compileren. assertis goed voor het controleren van een zaak tijdens runtime waarvan u verwacht dat deze altijd één resultaat zou hebben, maar op de een of andere manier een onverwacht resultaat zou kunnen opleveren onder onverwachte omstandigheden. U moet bijvoorbeeld alleen assertgebruiken om te bepalen of een aanwijzer die in een methode wordt doorgegeven, nullis, terwijl het lijkt alsof dat nooit zou mogen gebeuren. static_assertzou dat niet begrijpen.

  • Doen ze iets wat een simpele if-instructie niet kan doen?

assertkan worden gebruikt om de uitvoering van een programma te onderbreken, dus u kunt een ifgebruiken, een toepasselijke foutmelding, en vervolgens de uitvoering van het programma stoppen om een ​​soortgelijk effect te krijgen, maar assertis in dat geval iets eenvoudiger. static_assertis natuurlijk alleen geldig voor het detecteren van compilatieproblemen, terwijl een ifprogrammatisch geldig moet zijn en niet dezelfde verwachtingen kan evalueren tijdens het compileren. (Een ifkan echter worden gebruikt om tijdens runtime een foutmelding te geven.)

  • Is het een slechte gewoonte om ze te gebruiken?

Helemaal niet!


Antwoord 2, autoriteit 42%

static_assertis bedoeld om compilatiete laten mislukken met het opgegeven bericht, terwijl traditionele assertbedoeld is om de uitvoering van je programma te beëindigen.


Antwoord 3, autoriteit 14%

Ok, ik bijt:

  • Alleen static_assertwerkt als u wilt dat de compilatie zonder succes stopt als een statische voorwaarde wordt geschonden: static_assert(sizeof(void*) != 3, "Wrong machine word size");* Alleen dynamische beweringen kunnen dynamische voorwaarden opvangen: assert(argc == 1);

  • Eenvoudige if-instructies moeten geldig en compileerbaar zijn; statische beweringen veroorzaken compilatiefouten.

  • Nee.

*) Een praktisch voorbeeld is het voorkomen van misbruik van generieke sjabloonconstructies, zoals int x; std::move<int&&>(x).


Antwoord 4, autoriteit 6%

Is het een slechte gewoonte om ze te gebruiken?

Indien misbruikt, ja, vooral assert.

Eén misbruik hangt af van het feit dat die assert-statements actief zijn. Je moet nooit afhankelijk zijn van assertom iets te doen, omdat de code kan worden gecompileerd met NDEBUGgedefinieerd en dan doet assertniets. Productiecode wordt vaak gecompileerd met NDEBUGgedefinieerd om ervoor te zorgen dat die assert-statements verdwijnen.

Tenzij u een eenmalig programma schrijft dat niet langer dan een dag of twee zal duren, moet u het niet gebruiken om gebruikersinvoer te valideren. Het maakt gebruikers niet uit waar de code is mislukt, en het bericht dat wordt afgedrukt, ziet er voor veel gebruikers uit als een vreemde taal. Het vertelt de gebruiker niet hoe de fout moet worden opgelost. Het is ook erg meedogenloos, door het ontwerp. Het bericht dat wordt verzonden als reactie op een invoerfout van de gebruiker, moet een bericht zijn dat de gebruiker vertelt hoe het probleem kan worden opgelost. De beste actie na het bericht is om de gebruiker een manier te bieden om de fout te herstellen. Als dat niet mogelijk is, en als het enige haalbare antwoord is om het programma te beëindigen, moet het programma netjes worden beëindigd. Door het ontwerp resulteert assertniet in een schone afsluiting. Het roept abort()aan in plaats van exit().

Een gevolg van abort()op veel machines is het produceren van een core dump. Een core dump is een geweldige foutmelding voor een programmeur. Met een core dump kan een programmeur de debugger gebruiken om tot in detail te zien wat er mis is gegaan. Een nadeel van abort()is dat dingen niet worden opgeruimd. Abort “beëindigt het programma zonder destructors uit te voeren voor objecten met een automatische of statische opslagduur en zonder de functies aan te roepen die zijn doorgegeven aan atexit().”

Kortom: het is oké (en goed) om assertte gebruiken om te testen op programmeerfouten, maar alleen in een niet-productieomgeving. Gebruik iets anders om te testen op gebruikersfouten.


Antwoord 5, autoriteit 6%

static_assertis een compilerrichtlijn. Hiermee kunt u type-informatie controleren tijdens het compileren. Het zal een compilatiefout veroorzaken en een foutmelding produceren die in de meeste IDE’s wordt opgevangen en weergegeven in het foutvenster van de IDE.

static_assert(sizeof(int) == 4,"int should be 4 bytes");

assertis voor runtime, u kunt de waarde van een variabele controleren. Als de bewering mislukt, wordt de bewering geactiveerd. Dit zal een foutmeldingsvenster veroorzaken dat tijdens runtime verschijnt in sommige besturingssystemen (afhankelijk van de implementatie van de bewering)

assert(("mypointer  should never be null!", mypointer != nullptr));

Other episodes