OVH Cloud OVH Cloud

Gestion des Exceptions

25 réponses
Avatar
Michael Moreno
Bonjour,

Il me semble qu'en C++, le try-finally n'existe pas.

Je me demande par consequent quelle est la facon pour eviter la
repetition de code du genre

EnterCriticalSection(...);
try
{
...
LeaveCriticalSection(...);
}
catch(...)
{
LeaveCriticalSection(...);
}

Merci pour votre aide,

Michael

--
----
http://michael.moreno.free.fr/

10 réponses

1 2 3
Avatar
Arnaud Debaene
Michael Moreno wrote:
Merci a tous.

RAII
http://groups-beta.google.com/groups?as_q=RAII&safe=images&as_ugroup=fr.comp.lang.c%2B%2B&lr=&hl=en


Y a vraiment pas une autre solution ?
Cette solution est basee sur le "Out Of Scope" et dans certains cas je
trouve que c'est limitant.


Au contraire, c'est l'une des approches les plus puissantes que l'on ait
pour la gestion des ressources (au sens large, pas seulement la mémoire), et
c'est la solution "standard" en C++ . Qu'est ce qui te semble limitant là
dedans au juste? Donnes-nous un exemple où ce mécanisme ne serait pas
satisfaisant.

Arnaud


Avatar
Matthieu Moy
"Arnaud Debaene" writes:

Donnes-nous un exemple où ce mécanisme ne serait pas
satisfaisant.


Est-ce qu'on peut exprimer

Lock(A);
...
Lock(B);
...
Unlock(A);
...
Unlock(B);

?

--
Matthieu

Avatar
Marc Boyer
Bertrand Motuelle wrote:
Marc Boyer wrote:
In article , Michael Moreno wrote:
Bonjour,

Il me semble qu'en C++, le try-finally n'existe pas.

Je me demande par consequent quelle est la facon pour eviter la
repetition de code du genre

EnterCriticalSection(...);


{
Lock l();


Je ne suis pas sûr que la déclaration d'une fonction "l" ne prenant
pas de paramètre et retournant un object Lock soit d'un grand secours
;-)
Plutôt :
Lock l;


Tout à fait.

Marc Boyer
--
Je ne respecte plus le code de la route à vélo depuis une double fracture
due au fait que j'étais le seul à le respecter.



Avatar
Marc Boyer
Matthieu Moy wrote:
"Arnaud Debaene" writes:

Donnes-nous un exemple où ce mécanisme ne serait pas
satisfaisant.


Est-ce qu'on peut exprimer

Lock(A);
...
Lock(B);
...
Unlock(A);
...
Unlock(B);

?


Ca devient un peu plus complexe, mais c'est normal puisqu'un
principe de RAII est de libérer les ressources en ordre inverse
de leur aquisition, et que tu veux faire là le contraire.

Sans trop chercher, je ferais un truc du genre:

Lock *A= new Lock();
...
Lock *B= new Lock();
...
delete A;
...
delete B;

Bon, après, l'échec possible de new introduit un peut de travail
en plus. Peut-être qu'avec des aspects du langage que je maîtrise mal
(placement new ou factory), on pourrait éviter ce travers.
Faudrait je pense alors lancer une autre discussion avec un titre
qui ammène les gens plus experts que moi à se pencher sur ton problème.

Marc Boyer
--
Je ne respecte plus le code de la route à vélo depuis une double fracture
due au fait que j'étais le seul à le respecter.


Avatar
kanze
Michael Moreno wrote:

RAII

http://groups-beta.google.com/groups?as_q=RAII&safe=images&as_ugroup= fr.comp.lang.c%2B%2B&lr=&hl=en



Y a vraiment pas une autre solution ?


Bien sûr.

Cette solution est basee sur le "Out Of Scope" et dans certains cas
je

trouve que c'est limitant.


Quand l'idiome ne convient pas, il ne convient pas. C'est sûr. La
question initiale était par rapport à try/finally, ce qui introduite
une
portée aussi. Dans les deux cas, si la durée de vie déterminée par
la
portée d'une variable automatique ne te convient pas, il faut utiliser
d'autre chose. (Note bien que quelqu'un a cité boost::shared_ptr. Or,
un
boost::shared_ptr ne suit pas la portée d'une variable automatique.)

C'est un peu l'avantage d'un moyen extra linguistique pour gerer les
resssources. Comment, par exemple, faire en Java qu'une synchronisation
ne suis pas la durée de vie d'un bloc ? La contrapartie, évidemment,
c'est qu'il faut que tu fasses quelque chose -- try/finally, ou un
destructeur -- quand tu veux une durée de vie d'un bloc.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
kanze
Matthieu Moy wrote:
"Arnaud Debaene" writes:

Donnes-nous un exemple où ce mécanisme ne serait pas
satisfaisant.


Est-ce qu'on peut exprimer

Lock(A);
...
Lock(B);
...
Unlock(A);
...
Unlock(B);

?


Pas plus qu'avec try/finally. Ou plutôt avec les mêmes moyens. Dans
ce
cas-là, la RAII sert surtout de sauvegarde ; il assure que la
ressource
soit libérée, même en cas d'exception, mais la libération en cas
normal
est manuelle.

Sinon, il y a toujours quelque chose du genre :

std::deque< boost::shared_ptr >
locks ;
locks.push_front( new Lock( A ) ) ;
locks.push_front( new Lock( B ) ) ;

(Sauf que je ne crois pas que l'ordre des destructeurs n'est garantie
dans les collections standard. Mais ce ne serait pas difficile
d'écrire
un wrapper qui le fait.)

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Alexis Nikichine
Matthieu Moy wrote:
"Arnaud Debaene" writes:


Donnes-nous un exemple où ce mécanisme ne serait pas
satisfaisant.



Est-ce qu'on peut exprimer

Lock(A);
...
Lock(B);
...
Unlock(A);
...
Unlock(B);

?



Je m'étais fait une classe "Lock" de ce goût là, qui possédait une
méthode "earlyUnlock", pour unlocker mon mutex avant que le destructeur
ne le fasse lui-même.

Cela dit, je me permet d'attirer l'attention sur les ScopeGuard de
Alexandrescu, qui me paraissent bien résoudre ce problème, et permettent
aussi d'éviter d'écrire trop de petites classes ad-hoc:

http://www.cuj.com/documents/s€00/cujcexp1812alexandr/

Un exemple d'utilisation pour mettre un peu l'eau à la bouche:


{
FILE* topSecret = fopen("cia.txt");
ON_BLOCK_EXIT(std::fclose, topSecret);
... use topSecret ...
} // topSecret automagically closed



Alexis

--
Un certain domaine est libre


Avatar
Marc Boyer
In article <cporjn$4ng$, Marc Boyer wrote:
Matthieu Moy wrote:
"Arnaud Debaene" writes:

Donnes-nous un exemple où ce mécanisme ne serait pas
satisfaisant.


Est-ce qu'on peut exprimer

Lock(A);
...
Lock(B);
...
Unlock(A);
...
Unlock(B);

?


Ca devient un peu plus complexe, mais c'est normal puisqu'un
principe de RAII est de libérer les ressources en ordre inverse
de leur aquisition, et que tu veux faire là le contraire.

Sans trop chercher, je ferais un truc du genre:

Lock *A= new Lock();
...
Lock *B= new Lock();
...
delete A;
...
delete B;


Mais c'est bien sur non exception-safe, et c'est une solution comme
celle présentée par James qu'il faut prendre (ou revenir au try/catch).

Marc Boyer
--
Je ne respecte plus le code de la route à vélo depuis une double fracture
due au fait que j'étais le seul à le respecter.



Avatar
Olivier Huet
Bonjour,

Sans trop chercher, je ferais un truc du genre:

Lock *A= new Lock();
...
Lock *B= new Lock();
...
delete A;
...
delete B;


J'ai déjà (peut-être à tort) écrit du code ressemblant à ça, avec des
variables automatiques - genre (pour reprendre une classe proche) :

{
Lock l(A);
Lock l(B);
...
}

en comptant sur le fait que les destructeur * seraient * bien appelées
en ordre inverse des constructeurs, et j'ai vérifié avec le compilateur
que j'utilisait dans ce cas (VC++ 6).

En fait, ça me semblait logique que cela fonctionne comme ça, mais
finalement, était-ce standard : a-t-on ce genre de garantie ???


Olivier Huet

Avatar
Gabriel Dos Reis
Olivier Huet writes:

| en comptant sur le fait que les destructeur * seraient * bien appelées
| en ordre inverse des constructeurs, et j'ai vérifié avec le
| compilateur que j'utilisait dans ce cas (VC++ 6).
|
| En fait, ça me semblait logique que cela fonctionne comme ça, mais
| finalement, était-ce standard : a-t-on ce genre de garantie ???

Oui.

-- Gaby
1 2 3