int parse_natural_base_10_number(const char* s) {
int parsed = 0;
for (size_t i = 0; s[i] != '\0'; i++) {
parsed *= 10;
parsed += s[i] - '0';
}
return parsed;
}
Ongelma on, miten funktio voi välittää kutsuvalle ohjelmanosalle tiedon, jos parametri
s ei ole kelvollinen kokonaisluku.McCuen esittelemät 11 tapaa ovat karkeasti käännettynä:
- 1. Unohda koko juttu
- Jos virhe tapahtuu vain harvoin, niin ei ole hyödyllistä käyttää työaikaa siihen varautumiseen
- 2. Luovuta heti
- Et voi kuitenkaan korjata virhettä, joten ohjelman on sama kaatua heti
- 3. Palauta negatiivinen luku
- Jos funktio palauttaa normaalisti positiivisia lukuja, niin palauta virhetilanteessa negatiivinen tai muuten normaalin käsittelyalueen ulkopuolella oleva luku, esimerkiksi -1 tai 0x7fffffff
- 4. Palauta NULL-osoitin
- Jos funktio palauttaa normaalisti osoittimen muistialueelle, niin palauta virhetilanteessa NULL-osoitin
- 5. Palauta boolean-arvo
- Tallenna funktion normaali tulos parametrina annettuun osoitteeseen, ja palauta tosi tai epätosi sen mukaan, onnistuiko operaatio vai ei
- 6. Palauta virhekoodi
- Tallenna funktion tulos parametrina annettuun osoitteeseen, ja palauta enum-arvolla tieto onnistumisesta (esim PARSE_NATURAL_SUCCESS) tai virheen tarkempi syy (esim PARSE_NATURAL_BAD_CHARACTER)
- 7. Palauta boolean-arvo ja virheen sijainti
- Tallenna funktion tulos ja virheen sijainti parametreina annettuihin osoitteisiin, jotta funktiota kutsuva koodi voi muodostaa asiallisen virheilmoituksen, kun funktio palauttaa epätosi
- 8. Palauta virhekoodi ja lisätieto
- Jos funktio voi epäonnistua monella eri tavalla, niin palauta virhekoodi enum-arvona ja tallenna virhekoodia koskeva yksityiskohtainen lisätieto erillisessä parametrissa annettuun osoitteeseen
- 9. Aseta globaali virhelippu
- Tallenna virhekoodi ja virheen lisätiedot säikeen sisäiseen tai globaaliin muuttujaan, josta kutsuva koodi voi hakea ne tarvittaessa
- 10. Palauta tietue
- Palauta aina viittaus tietueeseen (struct), joka sisältää virhekoodin, funktion normaalin paluuarvon sekä mahdollisen virheen yksityiskohtaiset lisätiedot
- 11. Palauta virheolio
- Palauta viittaus geneeriseen virheolioon, jota voidaan pyytää muodostamaan varsinainen virheilmoitus tarvittaessa
Päivitys 19.2.2023: Martin Sústrik vertaa blogissaan C++:n ja C:n virhekäsittelyä. C++ sallii käsitellä virheet myös poikkeuksina, mutta poikkeukset eivät aina ole hyvä juttu!