Sobes.tech
Middle+

Que savez-vous des garanties de sécurité des exceptions?

sobes.tech IA

Réponse de l'IA

Les garanties de sécurité des exceptions déterminent le comportement d'une fonction en cas d'exception. Quatre niveaux de garanties sont distingués :

  1. Garantie de base (Basic guarantee) : Si la fonction lance une exception, le programme reste dans un état valide. Les ressources ne fuient pas (par exemple, la mémoire est libérée), mais l'état précis des objets peut être inconnu. La possibilité de continuer à travailler avec l'application est conservée.

    // Exemple de garantie de base
    void basic_guarantee_function(std::vector<int>& vec, int value) {
        // Des exceptions peuvent survenir lors de l'insertion
        vec.push_back(value); 
        // Si une exception se produit, vec peut être dans un état imprévisible (modifié partiellement),
        // mais la mémoire allouée pour vec sera correctement libérée à la sortie du scope.
    } 
    
  2. Garantie forte (Strong guarantee) : Si la fonction lance une exception, l'état du programme reste identique à celui avant l'appel. Toutes les modifications sont annulées.

    // Exemple de garantie forte
    // Utilisation de l'idiome Copy-and-Swap pour assurer la garantie forte
    class Resource {
        int* data;
        size_t size;
    public:
        Resource(size_t s) : size(s), data(new int[s]) {}
        ~Resource() { delete[] data; }
        Resource(const Resource& other) : size(other.size), data(new int[other.size]) {
            std::copy(other.data, other.data + size, data); // Peut lancer une exception
        }
        Resource& operator=(Resource other) // Transfert par valeur qui cause une copie
        {
            swap(*this, other); // Ne lance pas d'exception
            return *this;
        }
        friend void swap(Resource& first, Resource& second) noexcept {
            using std::swap;
            swap(first.data, second.data);
            swap(first.size, second.size);
        }
        // ... autres membres
    };
    
    void strong_guarantee_function(Resource& res, size_t new_size) {
        Resource temp(new_size); // Si une exception est levée ici, res ne changera pas
        res = temp;               // Utilisation de l'opérateur= surchargé qui garantit la garantie forte
    }
    
  3. Garantie d'absence d'exception (No-throw guarantee) : La fonction garantit qu'elle ne lancera pas d'exception. Ces fonctions sont marquées avec le spécificateur noexcept.

    // Exemple d'absence d'exception
    void no_throw_function() noexcept {
        // Pas d'opérations pouvant lancer une exception
        int a = 5;
        int b = 10;
        int c = a + b;
    }
    
  4. Garantie d'échec (Failure guarantee) : Dans le contexte de la sécurité des exceptions, ce niveau est parfois mentionné, ce qui signifie que la fonction peut laisser le programme dans un état indéfini, avec une fuite de ressources ou des défaillances. C'est en fait l'absence de garanties. Un tel comportement doit être évité.

L'importance des garanties de sécurité des exceptions réside dans la création d'un code fiable et prévisible, qui gère correctement les erreurs et les ressources même en cas d'exception. Le niveau de garantie choisi dépend de la criticité de l'opération, du coût du rollback et de la probabilité d'une exception.

Tableau comparatif des garanties :

Garantie État en cas d'exception Intégrité des données Fuites de ressources
De base Valide, mais indéfini Non garanti Non
Forte Non modifié (comme avant l'appel) Se conserve Non
Sans garantie Ne se produit jamais (pas d'exceptions) N/A N/A
Échec (sans garantie) Indéfini, possible dommage ou défaillances Non garanti Possible