Selon un auteur bien informé de la communauté C ++, le code ci-dessous ne doit pas compiler. il est faux?

StackOverflow https://stackoverflow.com/questions/8367459

Question

Selon Herb Sutter le code ci-dessous ne compilerait pas. Voir ce site http://www.gotw.ca/gotw/066.htm de où j'ai extrait le texte suivant, en ce qui concerne function-try-blocks:

Vers Certains Morals

Par ailleurs, cela signifie aussi que le seul (répétition seulement) utilisation possible pour un constructeur fonction bloc try est de traduire une exception levée d'une base ou un membre subobject. C'est Moral # 1. Ensuite, Moral # 2 dit que destructor fonction try-blocs sont entièrement usele -

"- Mais attendez!" J'entends quelqu'un d'interrompre à partir du milieu de la pièce. « Je ne suis pas d'accord avec Moral # 1. Je peux penser à une autre utilisation possible constructeur fonction try-blocs, à savoir les ressources attribuées gratuitement en la liste des initialiseur ou dans le corps du constructeur! "

Désolé, Nope. Après tout, rappelez-vous qu'une fois que vous entrez dans votre Le gestionnaire de constructeur try-bloc, toutes les variables locales dans la corps du constructeur sont également déjà hors de portée, et vous sont garantis qu'aucun des sous-objets de base ou des objets membres existent plus, la période. Tu ne peuvent pas se référer même à leurs noms. Soit les parties de votre objet étaient jamais construit, ou ceux qui ont été construits ont déjà été détruit. Donc, vous ne pouvez pas astiquer tout ce qui repose sur se référant à une base ou un membre de la classe (et de toute façon, c'est ce que les Destructeurs de base et sont membres, non?).

En supposant cette citation, le code suivant ne doit pas compiler, comme le cat objet a déjà été détruite au moment où les pistes de processus dans la clause de catch. Mais elle, au moins avec VSC2008.

class Cat
{
    public:
    Cat() { cout << "Cat()" << endl; }
    ~Cat() { cout << "~Cat()" << endl; }
};

class Dog
{
    public:
    Dog() { cout << "Dog()" << endl; throw 1; }
    ~Dog() { cout << "~Dog()" << endl; }
};


class UseResources
{
    class Cat *cat;
    class Dog dog;

    public:
    UseResources();
    ~UseResources() { delete cat; cat = NULL; cout << "~UseResources()" << endl; }
};

UseResources::UseResources() try : cat(new Cat), dog() { cout << "UseResources()" << endl; } catch(...)
{
    delete cat;
    throw;
}
Était-ce utile?

La solution

Je ne pense pas que Herb Sutter est en train de dire qu'il ne compilera pas. Il est en train d'expliquer les conséquences de ce que la norme doit dire au sujet de la situation (15.3.10):

En se référant à tout membre non-statique ou la classe de base d'un objet dans la gestionnaire pour une fonction-try-bloc d'un constructeur ou un destructeur pour que les résultats de l'objet dans comportement non défini .

Autres conseils

En supposant cette citation, le code suivant ne devrait pas ... compilation

Eh bien, il n'a pas dit qu'ils ne seraient jamais compiler. Si quoi que ce soit, j'interprété la citation signifie « faire ce n'est pas défini ». un comportement non défini est autorisé à avoir un résultat -. jusqu'à et y compris la compilation avec succès, et faire des choses surprenantes plus tard

Compilateurs sont différents, et aussi il y a des interrupteurs qui déterminent à quel point le compilateur sera stricte avec le code qu'il compile. ce code sera certainement provoquer des erreurs (fautes seg, etc.). essayez d'activer tous les commutateurs du compilateur pour le forcer à trouver cela.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top