 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Mickael Pointier Guest
|
Posted: Thu Apr 15, 2004 10:33 am Post subject: Suppression d'instances inutiles ? |
|
|
[Je viens de réinstaller mon PC suite à un changement d'OS, pourriez vous me
signaler le moindre problème dans ce message, que ca soit au niveau de
l'encodage ou que sais-je encore ? Merci d'avance.]
Je viens de passer de Visual 6 à VS.net 2003, et en convertissant mes
quelques projets C++, j'ai constaté un certain nombre de différences au
niveau du comportement de ces deux compilateurs. VS.net est visiblement bien
plus rigoureux et clair dans les erreurs qu'il signale, par contre il m'a
fait un truc que je n'ai pas trop aimé.
Ce que j'aimerai savoir si c'est lui qui a raison (la norme dit qu'il faut
le faire) et que donc je me reposait sur un comportement indéfini, ou bien
si ce que je faisait était pas mauvais en soit et que c'est donc VS.net qui
abuse.
Le point en question, c'est que dans ma librairie de déboggage, j'ai un
certain nombre de petites classes utilitaires qui n'ont de code que dans le
constructeur et dans le destructeur.
Certaines me servent à trouver des fuites de mémoire, d'autre à me sauver la
pile des appels dans un log, etc... tout ca ne sert qu'en debug, en release
le code en question est supprimé.
Vu que c'était pratique, j'ai débordé de l'usage purement debug, et j'ai
commencé à m'en servir, comme par exemple avec ma microclasse de
manipulation de répertoires:
==============
class tbDirectoryChanger
{
public:
tbDirectoryChanger(); //!< Simply store the current path
tbDirectoryChanger(const string &new_path); //!< Store the current path,
and set the new one
~tbDirectoryChanger(); //!< Restore the path stored during
construction
private:
void store_current_path(); //!< Utility function, store the current
path
string m_memo_path; //!< Contains the stored path
};
==============
C'est pas forcément très beau, mais ca me permet dans un outil de build de
ressources qui gère beaucoup de chemins d'accès de faire des trucs dans le
genre:
....
{
tbDirectoryChanger tbDC("mon nouveau chemin de travail temporaire");
DoSomething(bla sur le nouveau chemin);
}
....
ce qui fait qu'à la sortie du scope, le directory est automatiquement
restauré.
Avec VC6 ca marchait bien, VC7 lui considère que la variable "tbDC" n'est
pas utilisée, et donc il vire l'instanciation de ma variable, ce qui fait
que mon répertoire n'est pas changé, et mon "DoSomething" il fait n'importe
quoi vu que le répertoire n'est pas validé.
Donc il a le droit de faire ca ???
La variable n'est pas utilisée, soit, mais le constructeur et le destructeur
ne sont pas triviaux.
Vala, merci de m'éclairer là dessus.
Mike
|
|
| Back to top |
|
 |
Jean-Marc Bourguet Guest
|
Posted: Thu Apr 15, 2004 12:18 pm Post subject: Re: Suppression d'instances inutiles ? |
|
|
"Mickael Pointier" <mpointier (AT) eden-games (DOT) moc> writes:
| Quote: | C'est pas forcément très beau, mais ca me permet dans un outil de build de
ressources qui gère beaucoup de chemins d'accès de faire des trucs dans le
genre:
...
{
tbDirectoryChanger tbDC("mon nouveau chemin de travail temporaire");
DoSomething(bla sur le nouveau chemin);
}
...
ce qui fait qu'à la sortie du scope, le directory est automatiquement
restauré.
Avec VC6 ca marchait bien, VC7 lui considère que la variable "tbDC" n'est
pas utilisée, et donc il vire l'instanciation de ma variable, ce qui fait
que mon répertoire n'est pas changé, et mon "DoSomething" il fait n'importe
quoi vu que le répertoire n'est pas validé.
Donc il a le droit de faire ca ???
|
A ma connaissance, non.
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
|
|
| Back to top |
|
 |
Régis Troadec Guest
|
Posted: Thu Apr 15, 2004 12:25 pm Post subject: Re: Suppression d'instances inutiles ? |
|
|
"Mickael Pointier" <mpointier (AT) eden-games (DOT) moc> a écrit dans le message de
news:c5lob5$stc$1 (AT) aphrodite (DOT) grec.isp.9tel.net...
Salut,
[snip le reste]
| Quote: |
==============
class tbDirectoryChanger
{
public:
tbDirectoryChanger(); //!< Simply store the current path
tbDirectoryChanger(const string &new_path); //!< Store the current
path,
and set the new one
~tbDirectoryChanger(); //!< Restore the path stored during
construction
private:
void store_current_path(); //!< Utility function, store the
current
path
string m_memo_path; //!< Contains the stored path
};
==============
C'est pas forcément très beau, mais ca me permet dans un outil de build de
ressources qui gère beaucoup de chemins d'accès de faire des trucs dans
le
genre:
...
{
tbDirectoryChanger tbDC("mon nouveau chemin de travail temporaire");
DoSomething(bla sur le nouveau chemin);
}
...
ce qui fait qu'à la sortie du scope, le directory est automatiquement
restauré.
Avec VC6 ca marchait bien, VC7 lui considère que la variable "tbDC" n'est
pas utilisée, et donc il vire l'instanciation de ma variable, ce qui fait
que mon répertoire n'est pas changé, et mon "DoSomething" il fait
n'importe
quoi vu que le répertoire n'est pas validé.
|
Ca me parait tout a fait normal, à qui ou à quoi s'applique ta fonction
DoSomething ? Est-ce une fonction membre de tbDirectoryChanger, est-ce une
fonction statique ? Je ne le vois pas. Ta classe tbDirectoryChanger contient
une donnée membre string m_memo_path. Si DoSomething prend un string en
parametre, tu devrais avoir un accesseur pour passer le m_memo_path de ton
objet tbDC. Quelque chose du genre DoSomething(tbDEC.getPath()); par
exemple, avec std::string& getPath() const { return this->m_memo_path }
| Quote: |
Donc il a le droit de faire ca ???
|
Par *virer ton instance*, que fait-il exactement, tbDC n'est pas contruit ?
Ca m'étonne. La question est de savoir ce que tu passes comme paramètre à
DoSomething.
| Quote: |
La variable n'est pas utilisée, soit, mais le constructeur et le
destructeur
ne sont pas triviaux.
Vala, merci de m'éclairer là dessus.
Mike
|
Regis
|
|
| Back to top |
|
 |
Pierre Maurette Guest
|
Posted: Thu Apr 15, 2004 1:02 pm Post subject: Re: Suppression d'instances inutiles ? |
|
|
"Mickael Pointier" <mpointier (AT) eden-games (DOT) moc> typa:
| Quote: | [Je viens de réinstaller mon PC suite à un changement d'OS, pourriez vous me
signaler le moindre problème dans ce message, que ca soit au niveau de
l'encodage ou que sais-je encore ? Merci d'avance.]
Je viens de passer de Visual 6 à VS.net 2003, et en convertissant mes
quelques projets C++, j'ai constaté un certain nombre de différences au
niveau du comportement de ces deux compilateurs. VS.net est visiblement bien
plus rigoureux et clair dans les erreurs qu'il signale, par contre il m'a
fait un truc que je n'ai pas trop aimé.
Ce que j'aimerai savoir si c'est lui qui a raison (la norme dit qu'il faut
le faire) et que donc je me reposait sur un comportement indéfini, ou bien
si ce que je faisait était pas mauvais en soit et que c'est donc VS.net qui
abuse.
Le point en question, c'est que dans ma librairie de déboggage, j'ai un
certain nombre de petites classes utilitaires qui n'ont de code que dans le
constructeur et dans le destructeur.
Certaines me servent à trouver des fuites de mémoire, d'autre à me sauver la
pile des appels dans un log, etc... tout ca ne sert qu'en debug, en release
le code en question est supprimé.
Vu que c'était pratique, j'ai débordé de l'usage purement debug, et j'ai
commencé à m'en servir, comme par exemple avec ma microclasse de
manipulation de répertoires:
==============
class tbDirectoryChanger
{
public:
tbDirectoryChanger(); //!< Simply store the current path
tbDirectoryChanger(const string &new_path); //!< Store the current path,
and set the new one
~tbDirectoryChanger(); //!< Restore the path stored during
construction
private:
void store_current_path(); //!< Utility function, store the current
path
string m_memo_path; //!< Contains the stored path
};
==============
C'est pas forcément très beau, mais ca me permet dans un outil de build de
ressources qui gère beaucoup de chemins d'accès de faire des trucs dans le
genre:
...
{
tbDirectoryChanger tbDC("mon nouveau chemin de travail temporaire");
DoSomething(bla sur le nouveau chemin);
}
...
ce qui fait qu'à la sortie du scope, le directory est automatiquement
restauré.
Avec VC6 ca marchait bien, VC7 lui considère que la variable "tbDC" n'est
pas utilisée, et donc il vire l'instanciation de ma variable, ce qui fait
que mon répertoire n'est pas changé, et mon "DoSomething" il fait n'importe
quoi vu que le répertoire n'est pas validé.
Donc il a le droit de faire ca ???
La variable n'est pas utilisée, soit, mais le constructeur et le destructeur
ne sont pas triviaux.
Vala, merci de m'éclairer là dessus.
J'avais remarqué que VC++7 avait l'optimisation virile et joyeuse. |
Normal ou pas normal, je n'en sais pas assez en C++ et sur le
DoSomething pour me prononcer.
A tout hasard, essayez:
volatile tbDirectoryChanger tbDC("repert");
Pierre
|
|
| Back to top |
|
 |
Laurent Deniau Guest
|
Posted: Thu Apr 15, 2004 1:41 pm Post subject: Re: Suppression d'instances inutiles ? |
|
|
Pierre Maurette wrote:
| Quote: | "Mickael Pointier" <mpointier (AT) eden-games (DOT) moc> typa:
[Je viens de réinstaller mon PC suite à un changement d'OS, pourriez vous me
signaler le moindre problème dans ce message, que ca soit au niveau de
l'encodage ou que sais-je encore ? Merci d'avance.]
Je viens de passer de Visual 6 à VS.net 2003, et en convertissant mes
quelques projets C++, j'ai constaté un certain nombre de différences au
niveau du comportement de ces deux compilateurs. VS.net est visiblement bien
plus rigoureux et clair dans les erreurs qu'il signale, par contre il m'a
fait un truc que je n'ai pas trop aimé.
Ce que j'aimerai savoir si c'est lui qui a raison (la norme dit qu'il faut
le faire) et que donc je me reposait sur un comportement indéfini, ou bien
si ce que je faisait était pas mauvais en soit et que c'est donc VS.net qui
abuse.
Le point en question, c'est que dans ma librairie de déboggage, j'ai un
certain nombre de petites classes utilitaires qui n'ont de code que dans le
constructeur et dans le destructeur.
Certaines me servent à trouver des fuites de mémoire, d'autre à me sauver la
pile des appels dans un log, etc... tout ca ne sert qu'en debug, en release
le code en question est supprimé.
Vu que c'était pratique, j'ai débordé de l'usage purement debug, et j'ai
commencé à m'en servir, comme par exemple avec ma microclasse de
manipulation de répertoires:
==============
class tbDirectoryChanger
{
public:
tbDirectoryChanger(); //!< Simply store the current path
tbDirectoryChanger(const string &new_path); //!< Store the current path,
and set the new one
~tbDirectoryChanger(); //!< Restore the path stored during
construction
private:
void store_current_path(); //!< Utility function, store the current
path
string m_memo_path; //!< Contains the stored path
};
==============
C'est pas forcément très beau, mais ca me permet dans un outil de build de
ressources qui gère beaucoup de chemins d'accès de faire des trucs dans le
genre:
...
{
tbDirectoryChanger tbDC("mon nouveau chemin de travail temporaire");
DoSomething(bla sur le nouveau chemin);
}
...
ce qui fait qu'à la sortie du scope, le directory est automatiquement
restauré.
Avec VC6 ca marchait bien, VC7 lui considère que la variable "tbDC" n'est
pas utilisée, et donc il vire l'instanciation de ma variable, ce qui fait
que mon répertoire n'est pas changé, et mon "DoSomething" il fait n'importe
quoi vu que le répertoire n'est pas validé.
Donc il a le droit de faire ca ???
La variable n'est pas utilisée, soit, mais le constructeur et le destructeur
ne sont pas triviaux.
Vala, merci de m'éclairer là dessus.
J'avais remarqué que VC++7 avait l'optimisation virile et joyeuse.
Normal ou pas normal, je n'en sais pas assez en C++ et sur le
DoSomething pour me prononcer.
A tout hasard, essayez:
volatile tbDirectoryChanger tbDC("repert");
|
Cela ne devrait rien changer.
Le constructeur non trivial et inconnu dans l'unite de compilation a le
droit d'avoir des effets de bords. Le compilateur doit donc construire
tbDC imperativement. La duree de vie de tbDC va jusqu'a la fin du bloc
courant donc au-dela de DoSomething. Je pencherais pour un bug mais ca
me parait enorme comme bug (difficile de croire qu'il n'ait pas ete
detecte par les ecrivains du compilateur). Peut-etre faudrait-il voir le
code du constructeur et de DoSomething pour en avoir le coeur net?
a+, ld.
|
|
| Back to top |
|
 |
Pierre Maurette Guest
|
Posted: Thu Apr 15, 2004 3:11 pm Post subject: Re: Suppression d'instances inutiles ? |
|
|
Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> typa:
| Quote: | Pierre Maurette wrote:
[...]
J'avais remarqué que VC++7 avait l'optimisation virile et joyeuse.
Normal ou pas normal, je n'en sais pas assez en C++ et sur le
DoSomething pour me prononcer.
A tout hasard, essayez:
volatile tbDirectoryChanger tbDC("repert");
Cela ne devrait rien changer.
Non, parce que ce n'est pas nécessaire, le problème est ailleurs. |
C'est marrant, le volatile. Vous faites :
volatile int c = 12;
c=c;
c=c;
// rien d'autre pour c
il génère:
12 -> mémoire
mémoire -> registre
registre -> mémoire
mémoire -> registre
registre -> mémoire
| Quote: | Le constructeur non trivial et inconnu dans l'unite de compilation a le
droit d'avoir des effets de bords. Le compilateur doit donc construire
tbDC imperativement. La duree de vie de tbDC va jusqu'a la fin du bloc
courant donc au-dela de DoSomething. Je pencherais pour un bug mais ca
me parait enorme comme bug (difficile de croire qu'il n'ait pas ete
detecte par les ecrivains du compilateur). Peut-etre faudrait-il voir le
code du constructeur et de DoSomething pour en avoir le coeur net?
|
J'ai vérifié rapidement sans écrire les constructeurs ni destructeurs.
Le lieur me jette, mais c'est pas grave. Le constructeur est bien
appelé au moment de l'instanciation, et le destructeur à la fin de la
fonction. Avec VC++ 7.1 full, en release optimisée.
Doit y avoir du bug ailleurs.
Pour Mickael, vérifier en ajoutant l'option /FAs à la compilation, et
en regardant le fichier .asm (rechercher sur les mots du source, c'est
à la fin d'un gros fichier).
Pierre
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Thu Apr 15, 2004 4:21 pm Post subject: Re: Suppression d'instances inutiles ? |
|
|
"Mickael Pointier" <mpointier (AT) eden-games (DOT) moc> wrote
[...]
| Quote: | Le point en question, c'est que dans ma librairie de déboggage, j'ai
un certain nombre de petites classes utilitaires qui n'ont de code que
dans le constructeur et dans le destructeur.
|
Je me sers souvent des classes comme ça. Et non seulement pour des
motifs de mise au point ; c'est un idiome assez courant.
| Quote: | Certaines me servent à trouver des fuites de mémoire, d'autre à me
sauver la pile des appels dans un log, etc... tout ca ne sert qu'en
debug, en release le code en question est supprimé.
|
Je m'em sers pratiquement chaque fois que j'ai une ressource à gerer,
qui doit être impérativement libérée lorsque je pars, y compris si je
pars à cause d'une interruption.
| Quote: | Vu que c'était pratique, j'ai débordé de l'usage purement debug, et
j'ai commencé à m'en servir, comme par exemple avec ma microclasse de
manipulation de répertoires:
==============
class tbDirectoryChanger
{
public:
tbDirectoryChanger(); //!< Simply store the current path
tbDirectoryChanger(const string &new_path); //!< Store the current path,
and set the new one
~tbDirectoryChanger(); //!< Restore the path stored during
construction
private:
void store_current_path(); //!< Utility function, store the current
path
string m_memo_path; //!< Contains the stored path
};
==============
C'est pas forcément très beau, mais ca me permet dans un outil de
build de ressources qui gère beaucoup de chemins d'accès de faire des
trucs dans le genre:
|
C'est même l'idiome consacré en C++. Ça s'appelle RAII (Resource
Acquisition Is Initialization), pour des raisons historiques, mais on
s'en sert aujourd'hui pour beaucoup plus que seulement gerer des
ressources. Et si tu veux écrire du code « exception safe », il n'y a
que ça pour la gestion des ressources.
| Quote: | ...
{
tbDirectoryChanger tbDC("mon nouveau chemin de travail temporaire");
DoSomething(bla sur le nouveau chemin);
}
...
ce qui fait qu'à la sortie du scope, le directory est automatiquement
restauré.
|
Tout à fait. Y compris si tu en sors suite à une interruption. C'est
tout l'intérêt de l'idiome.
| Quote: | Avec VC6 ca marchait bien, VC7 lui considère que la variable "tbDC"
n'est pas utilisée, et donc il vire l'instanciation de ma variable, ce
qui fait que mon répertoire n'est pas changé, et mon "DoSomething" il
fait n'importe quoi vu que le répertoire n'est pas validé.
|
J'ai dû mal à croire qu'il puisse avoir une erreur aussi grossière. Une
telle erreur rendrait le compilateur quasiment inutilisable avec du C++
moderne (Boost, etc.). Si c'était le cas, je crois qu'on en aurait
entendu parler déjà.
| Quote: | Donc il a le droit de faire ca ???
|
Certainement pas. Seulement si le constructeur et le destructeur sont
triviaux. C-à-d pas écrit par l'utilisateur.
| Quote: | La variable n'est pas utilisée, soit, mais le constructeur et le
destructeur ne sont pas triviaux.
|
La variable *est* utilisée. Ce n'est pas parce que tu ne la référence
pas une fois qu'elle est construite qu'elle ne sert pas.
--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
|
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Thu Apr 15, 2004 6:15 pm Post subject: Re: Suppression d'instances inutiles ? |
|
|
On Thu, 15 Apr 2004 12:33:32 +0200, "Mickael Pointier"
<mpointier (AT) eden-games (DOT) moc> wrote:
| Quote: | j'ai un
certain nombre de petites classes utilitaires qui n'ont de code que dans le
constructeur et dans le destructeur.
|
J'ai cru comprendre que ce genre de technique était également assez
courant dans wxWidget (anciennement wxWindows). Donc effectivement, si
VC++ vire ces objets avant l'heure, ça risque d'être sérieusement
problématique :-(
--
FLL, Epagneul Breton
|
|
| Back to top |
|
 |
Alexandre Guest
|
Posted: Thu Apr 15, 2004 6:32 pm Post subject: Re: Suppression d'instances inutiles ? |
|
|
| Quote: | ==============
class tbDirectoryChanger
{
public:
tbDirectoryChanger(); //!< Simply store the current path
tbDirectoryChanger(const string &new_path); //!< Store the current
path,
and set the new one
~tbDirectoryChanger(); //!< Restore the path stored during
construction
private:
void store_current_path(); //!< Utility function, store the
current
path
string m_memo_path; //!< Contains the stored path
};
==============
|
on a pas le code des méthodes. Je fais donc un essai avec un corps
simplissime (mais non vide).
| Quote: | {
tbDirectoryChanger tbDC("mon nouveau chemin de travail temporaire");
DoSomething(bla sur le nouveau chemin);
}
|
Idem, on a pas le code (ni le proto) de DoSomething. Donc je fais un truc
simplissime pour tester.
Mon compilo C++ (borland C++ builder) passe tout sans pb (aucun warning) la
variable est bien construite puis détruite.
ça serait étrange que visual studio renferme un bug aussi gros. Un peu plus
de détails sur cette classe et DoSomething nous aiderait...
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Fri Apr 16, 2004 7:38 am Post subject: Re: Suppression d'instances inutiles ? |
|
|
Pierre Maurette <maurette.pierre (AT) free (DOT) fr> wrote
| Quote: | J'avais remarqué que VC++7 avait l'optimisation virile et joyeuse.
Normal ou pas normal, je n'en sais pas assez en C++ et sur le
DoSomething pour me prononcer.
A tout hasard, essayez:
volatile tbDirectoryChanger tbDC("repert");
|
On programme à coups d'hazard, maintenant. Si le programme ne marche
pas, on modifie quelque chose de façon aléatoire, en espérant que par je
ne sais pas quelle miracle, il va se mettre à marcher.
J'espère ne jamais avoir à utiliser un programme que tu as écrit.
En fait, il doit bel et bien y avoir une erreur quelque part, et je
doute que ce soit le compilateur -- l'erreur serait trop grosse. Mais ça
doit être facile à mettre en évidence : il doit suffir d'activer les
traces qu'il a sûrement mis dans le constructeur et le destructeur, pour
voir bien si on y passe ou non.
--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Fri Apr 16, 2004 7:56 am Post subject: Re: Suppression d'instances inutiles ? |
|
|
Pierre Maurette <maurette.pierre (AT) free (DOT) fr> wrote
| Quote: | Laurent Deniau <Laurent.Deniau (AT) cern (DOT) ch> typa:
Pierre Maurette wrote:
[...]
J'avais remarqué que VC++7 avait l'optimisation virile et joyeuse.
Normal ou pas normal, je n'en sais pas assez en C++ et sur le
DoSomething pour me prononcer.
A tout hasard, essayez:
volatile tbDirectoryChanger tbDC("repert");
Cela ne devrait rien changer.
Non, parce que ce n'est pas nécessaire, le problème est ailleurs.
C'est marrant, le volatile. Vous faites :
volatile int c = 12;
c=c;
c=c;
// rien d'autre pour c
il génère:
12 -> mémoire
mémoire -> registre
registre -> mémoire
mémoire -> registre
registre -> mémoire
|
Ce qui me semble tout à fait normal.
Sur une machine moderne, je m'attendrais aussi à ce que le compilateur
ajoute des barrières d'écriture et de lecture, de façon à s'assurer que
les l'écritures soient bien visibles de l'exterieur, et que les lectures
va réelement chercher au delà de la cache, mais la plupart des
compilateurs ne le font pas.
D'après tes commentaires, j'ai l'impression que vous ne connaissez pas
la signification de volatile. Ce qui n'est pas grave en soi -- un
programmeur d'applications n'en a jamais besoin. Mais dans ce cas-là, il
ne faut pas s'en servir n'en plus. Ni en conseiller l'utilisation à
d'autres.
| Quote: | Le constructeur non trivial et inconnu dans l'unite de compilation a
le droit d'avoir des effets de bords. Le compilateur doit donc
construire tbDC imperativement. La duree de vie de tbDC va jusqu'a la
fin du bloc courant donc au-dela de DoSomething. Je pencherais pour
un bug mais ca me parait enorme comme bug (difficile de croire qu'il
n'ait pas ete detecte par les ecrivains du compilateur). Peut-etre
faudrait-il voir le code du constructeur et de DoSomething pour en
avoir le coeur net?
|
Il faudrait bien en effet savoir exactement le contexte. Parce que je ne
peux pas croire que le compilateur ôte systèmatiquement de telles
variables. Comme j'ai écris par ailleurs, ça fait partie d'un idiome
consacré (RAII), décrit dans prèsque tous les textes C++.
| Quote: | J'ai vérifié rapidement sans écrire les constructeurs ni destructeurs.
Le lieur me jette, mais c'est pas grave. Le constructeur est bien
appelé au moment de l'instanciation, et le destructeur à la fin de la
fonction. Avec VC++ 7.1 full, en release optimisée. Doit y avoir du
bug ailleurs.
Pour Mickael, vérifier en ajoutant l'option /FAs à la compilation, et
en regardant le fichier .asm (rechercher sur les mots du source, c'est
à la fin d'un gros fichier).
|
Et quoi encore ?
S'il a un mechanisme de trace (fortement conseillé pour tout sauf les
programmes les plus petits), il n'a que l'activer. S'il n'en a pas, il
pourrait penser d'y en ajouter un. Et en attendant, des sorties vers
std::cerr permet d'avancer -- est-ce que le constructeur est réelement
appelé ? Sinon, est-ce qu'on passe par le code où la variable est
déclarée ; si oui, est-ce que l'essai de changer le répertoire a
réussi@? (A priori, s'il y a eu un échec lors de l'essai de changer le
répertoire, une erreur aurait dû être logguée. Sauf qu'il me semble que
Michael a dit une fois qu'il travaille sur des jeux. Un domain que je ne
connais pas, mais où les règles de programmation son bien différentes
que ce que je vois d'habitude. C'est donc peut-être normal ou acceptable
qu'il n'a pas loggué l'erreur -- qu'est-ce qu'on ferait avec un log d'un
programme de jeu ?)
--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
|
|
| Back to top |
|
 |
Mickael Pointier Guest
|
Posted: Fri Apr 16, 2004 8:26 am Post subject: Re: Suppression d'instances inutiles ? |
|
|
Alexandre wrote:
| Quote: | ==============
class tbDirectoryChanger
{
public:
tbDirectoryChanger(); //!< Simply store the current path
tbDirectoryChanger(const string &new_path); //!< Store the
current path, and set the new one
~tbDirectoryChanger(); //!< Restore the path stored
during construction
private:
void store_current_path(); //!< Utility function, store the
current path
string m_memo_path; //!< Contains the stored path
};
==============
on a pas le code des méthodes. Je fais donc un essai avec un corps
simplissime (mais non vide).
|
Oui, ca suffit.
| Quote: | [...]
Mon compilo C++ (borland C++ builder) passe tout sans pb (aucun
warning) la variable est bien construite puis détruite.
ça serait étrange que visual studio renferme un bug aussi gros. Un
peu plus de détails sur cette classe et DoSomething nous aiderait...
|
Bon, j'ai trouvé ce qui se passe.
Moi bettement je pensait que ces deux écritures étaient équivalentes:
tbDirectoryChanger tbdc;
et
tbDirectoryChanger tbdc();
Visiblement ca n'est pas le cas, car si je compile avec .net (Version
7.1.3088 en anglais) en debug (je n'ai pas essayé en release) j'ai un
comportement différent selon l'écriture utilisée.
En clair, si j'écrit ca:
tbDirectoryChanger tbDC;
l'objet est correctement créé et détruit, le chemin mémorisé et restauré.
Si j'écrit ca:
tbDirectoryChanger tbDC("Un chemin quelconque");
l'objet est correctement créé avec le chemin bien modifié puis l'ancien
restauré à la destruction.
Par contre si j'écrit ca:
tbDirectoryChanger tbDC();
j'ai le droit à un message:
warning C4930: 'tbDirectoryChanger tbDC(void)': prototyped function not
called (was a variable definition intended?)
En quoi cette écriture est-elle fausse ? Ca ne revient pas à dire "utilise
le constructeur non paramétré" ?
Si quelqu'un pouvait m'éclairer sur le problème, ca serait cool :)
Mike
|
|
| Back to top |
|
 |
Pierre Maurette Guest
|
Posted: Fri Apr 16, 2004 9:04 am Post subject: Re: Suppression d'instances inutiles ? |
|
|
[email]kanze (AT) gabi-soft (DOT) fr[/email] typa:
| Quote: | Pierre Maurette <maurette.pierre (AT) free (DOT) fr> wrote in message
news:<gm0t70917it87q89qds50ns3m55jrph89m (AT) 4ax (DOT) com>...
J'avais remarqué que VC++7 avait l'optimisation virile et joyeuse.
Normal ou pas normal, je n'en sais pas assez en C++ et sur le
DoSomething pour me prononcer.
A tout hasard, essayez:
volatile tbDirectoryChanger tbDC("repert");
On programme à coups d'hazard, maintenant. Si le programme ne marche
pas, on modifie quelque chose de façon aléatoire, en espérant que par je
ne sais pas quelle miracle, il va se mettre à marcher.
Cool, Raoul. |
<OP>
Avec VC6 ca marchait bien, VC7 lui considère que la variable "tbDC"
n'est pas utilisée, et donc il vire l'instanciation de ma variable, ce
qui fait que mon répertoire n'est pas changé, et mon "DoSomething" il
fait n'importe quoi vu que le répertoire n'est pas validé.
</OP>
Mode affirmatif, donc je suppose que l'OP a pris les moyens de
vérifier que sa classe n'avait pas été instanciée. J'ai de gros
doutes, je ne vois pas le compilateur zapper du code de constructeur
et destructeur. Mais par politesse (eh oui) je mets sur le même plan
mes doutes sur VC++ et sur son DoSomething. C'est une figure de
réthorique qui permet de ne pas passer pour un goujat.
Je connais un peu le comportement (radical) de VC++7.1 face à
volatile. Saisir 9 caractères pour lever un doute, ce n'est pas cher.
De plus, j'avoue que le C++ me réserve encore bien des surprises (et
pour longtemps encore:-() et je voulais vérifier. Votre message
précédent m'aurait totallement rassuré, mais il est arrivé un peu
tard.
Dans un second message que vous semblez ignorer, je signale que j'ai
testé sur le compilateur utilisé par l'OP et que la classe s'instancie
normalement : c'est LA réponse à LA question posée :
<OP>
Donc il a le droit de faire ca ???
</OP>
Il ne fait pas ça (VC++ .NET 2003). J'en profite pour donner une
méthode parmi d'autre pour lever tout doute sur le contenu de la
"release". La tentation est grande de se contenter de se mettre en
configuration "debug" et de tracer.
| Quote: | J'espère ne jamais avoir à utiliser un programme que tu as écrit.
Dieu m'en préserve également, ce serait un grand honneur pour moi, |
mais je craindrais des effets de bord. Je le regrette.
Pierre
|
|
| Back to top |
|
 |
Mickael Pointier Guest
|
Posted: Fri Apr 16, 2004 9:58 am Post subject: Re: Suppression d'instances inutiles ? |
|
|
| Quote: | Le constructeur non trivial et inconnu dans l'unite de compilation a
le droit d'avoir des effets de bords. Le compilateur doit donc
construire tbDC imperativement. La duree de vie de tbDC va jusqu'a
la fin du bloc courant donc au-dela de DoSomething. Je pencherais
pour un bug mais ca me parait enorme comme bug (difficile de croire
qu'il n'ait pas ete detecte par les ecrivains du compilateur).
Peut-etre faudrait-il voir le code du constructeur et de
DoSomething pour en avoir le coeur net?
Il faudrait bien en effet savoir exactement le contexte. Parce que je
ne peux pas croire que le compilateur ôte systèmatiquement de telles
variables. Comme j'ai écris par ailleurs, ça fait partie d'un idiome
consacré (RAII), décrit dans prèsque tous les textes C++.
|
Depuis mon autre message où j'ai indiqué que le problème ne se produisait
que si j'utilisais la forme avec parenthèse, j'ai voulu voir si le
compilateur générait un code différent dans le cas où j'utilise new:
Que je fasses ca:
tbDirectoryChanger *ptr_tbdc=new tbDirectoryChanger;
ou ca:
tbDirectoryChanger *ptr_tbdc=new tbDirectoryChanger();
J'obtient ca:
00428DF4 push 1Ch
00428DF6 call operator new (43FAA0h)
00428DFB add esp,4
00428DFE mov dword ptr [ebp-0CDCh],eax
00428E04 mov byte ptr [ebp-4],5
00428E08 cmp dword ptr [ebp-0CDCh],0
00428E0F je Tool_Main+144h (428E24h)
00428E11 mov ecx,dword ptr [ebp-0CDCh]
00428E17 call tbDirectoryChanger::tbDirectoryChanger (445320h)
00428E1C mov dword ptr [ebp-0D68h],eax
00428E22 jmp Tool_Main+14Eh (428E2Eh)
00428E24 mov dword ptr [ebp-0D68h],0
00428E2E mov eax,dword ptr [ebp-0D68h]
00428E34 mov dword ptr [ebp-0CD8h],eax
00428E3A mov byte ptr [ebp-4],3
00428E3E mov ecx,dword ptr [ebp-0CD8h]
00428E44 mov dword ptr [ptr_tbdc],ecx
La différence de comportement n'est donc que dans l'instantiation simple.
| Quote: | S'il a un mechanisme de trace (fortement conseillé pour tout sauf les
programmes les plus petits), il n'a que l'activer. S'il n'en a pas, il
pourrait penser d'y en ajouter un. Et en attendant, des sorties vers
std::cerr permet d'avancer -- est-ce que le constructeur est réelement
appelé ? Sinon, est-ce qu'on passe par le code où la variable est
déclarée ; si oui, est-ce que l'essai de changer le répertoire a
réussi@? (A priori, s'il y a eu un échec lors de l'essai de changer le
répertoire, une erreur aurait dû être logguée. Sauf qu'il me semble
que Michael a dit une fois qu'il travaille sur des jeux. Un domain
que je ne connais pas, mais où les règles de programmation son bien
différentes que ce que je vois d'habitude. C'est donc peut-être
normal ou acceptable qu'il n'a pas loggué l'erreur -- qu'est-ce qu'on
ferait avec un log d'un programme de jeu ?)
|
Dans un outil, et tout est bien loggé, c'est comme ca que je me suis rendu
compte du problème.
L'outil exécute des scripts, et chaque fois que je fais une grosse
modification je lance mes scripts de test, et là ca à foiré.
Mais bon, y'a log et log.
Il me semble normal de détecter qu'une opération de changement de répertoire
échoue.
Par contre détecter le fait que le compilateur à décidé de ne pas appeller
le code en question, heu, je sais pas faire, si ce n'est en le déduisant du
fait que le code derrière foire lamentablement.
Mike
|
|
| Back to top |
|
 |
Twxs Guest
|
Posted: Fri Apr 16, 2004 10:19 am Post subject: Re: Suppression d'instances inutiles ? |
|
|
Régis Troadec wrote:
| Quote: | "Mickael Pointier" <mpointier (AT) eden-games (DOT) moc> a écrit dans le message de
news:c5lob5$stc$1 (AT) aphrodite (DOT) grec.isp.9tel.net...
Salut,
[snip le reste]
genre:
...
{
tbDirectoryChanger tbDC("mon nouveau chemin de travail temporaire");
DoSomething(bla sur le nouveau chemin);
}
...
ce qui fait qu'à la sortie du scope, le directory est automatiquement
restauré.
Ca me parait tout a fait normal, à qui ou à quoi s'applique ta fonction
DoSomething ? Est-ce une fonction membre de tbDirectoryChanger, est-ce une
fonction statique ? Je ne le vois pas.
|
tu n'as pas tout saisi, le DoSomething n'a rien a voire avec la classe
tbDirectoryChanger, elle indique juste une chose a faire dans le nouveau
repertoire courant
sinon, j'utilise frequement ce genre de technique et n'ai aucun probleme
sous tous les VC (6, 7.0 et 7.1). Bienqu'il me semble qu'une option de
compilation retire le code non utilisé, verifie qu'elle ne soit pas
activée.
Twxs
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|