Vraag Wat zegt de C ++-standaard over het negeren van een throw () -functie met no-except?


Het volgende lijkt te compileren op een aantal compilers die ik heb geprobeerd:

class A
{
public:
    virtual void foo() throw() = 0;
};

class B : public A
{
public:
    virtual void foo() noexcept override { }
};

Het lijkt erop dat men een throw () -functie kan negeren met de nieuwere no-concept-specificatie. Ik probeerde ook het tegenovergestelde (het overschrijven van noexcept met throw ()) en het lijkt te werken. Waarom is dat? Is dit niet-gedefinieerde gedrag of is dit toegestaan?

Houd er rekening mee dat het genereren van code wordt beïnvloed door noexcept vs throw (). Ze hebben ook geen equivalent gedrag, omdat noexcept een andere beëindigingsfunctie aanroept dan throw (). Een ideaal antwoord roept de verschillen in gedrag op en waarom ze in dit geval wel of niet belangrijk zijn.


11
2017-10-24 19:42


oorsprong


antwoorden:


U kunt dit zelfs doen zonder de doorslag te geven:

void f() throw();
void f() noexcept { throw 1; }

[Except.spec] / 9 maakt duidelijk dat het de specificatie op de definitie die bepaalt wat er gebeurt:

Wanneer een uitzondering van type E wordt gegenereerd en de zoektocht naar een handler   ([except.handle]) ontmoet het buitenste blok van een functie met een   uitzonderingsspecificatie die E niet toestaat, dan

  • als de functiedefinitie a heeft dynamic-uitzondering-specificatie, de   functie std::unexpected() wordt aangeroepen ([except.unexpected]),

  • anders de functie std::terminate() wordt genoemd   ([Except.terminate]).

Dit is geen probleem, want wat voor speciale behandeling dan ook, dit gebeurt bij de persoon die op de hoogte is, niet de beller; de beller moet weten dat geen enkele uitzondering de functie ooit zal verlaten.


3
2017-10-25 06:40



Is dit niet-gedefinieerde gedrag of is dit toegestaan?   Dit is toegestaan.

Van de C ++ standaard:

Als een virtuele functie een uitzonderingsspecificatie heeft, allemaal   verklaringen, inclusief de definitie, van elke functie die de prioriteit overschrijft   die virtuele functie in een afgeleide klasse staat alleen uitzonderingen toe   die zijn toegestaan ​​door de uitzonderingsspecificatie van de basisklasse   virtuele functie, tenzij de overschrijvende functie is gedefinieerd als   verwijderd.

Praktisch: u kunt de methode overschrijven in de afgeleide klasse en nieuwe regels opgeven naast die die door de basisklasse zijn opgegeven.

In jouw voorbeeld throw() en noexcept zijn gelijkwaardig.


2
2017-10-24 19:50