 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Aurélien Barbier-Accary Guest
|
Posted: Wed Oct 12, 2005 11:03 am Post subject: sizeof et virtual |
|
|
Bonjour,
avant ma question, voici les données :
class cA
{
protected:
double d;
public:
cA(const double& d =0.0) { this->d = d; }
~cA(void) {}
};
class cB
{
protected:
double d;
public:
cB(const double& d =0.0) { this->d = d; }
virtual ~cB(void) {}
};
cout << "sizeof(cA) = " << sizeof(cA) << endl; // => 8
cout << "sizeof(cB) = " << sizeof(cB) << endl; // => 16
est-ce normal ?
peut-on garder une taille de 8 en utilisant des fonctions virtuelles ?
Merci.
Aurélien.
|
|
| Back to top |
|
 |
Marc Boyer Guest
|
Posted: Wed Oct 12, 2005 11:22 am Post subject: Re: sizeof et virtual |
|
|
Aurélien Barbier-Accary <nospam_star-shoot_mapson (AT) fr (DOT) st> a écrit :
| Quote: | avant ma question, voici les données :
class cA
{
protected:
double d;
public:
cA(const double& d =0.0) { this->d = d; }
~cA(void) {}
};
class cB
{
protected:
double d;
public:
cB(const double& d =0.0) { this->d = d; }
virtual ~cB(void) {}
};
cout << "sizeof(cA) = " << sizeof(cA) << endl; // => 8
cout << "sizeof(cB) = " << sizeof(cB) << endl; // => 16
est-ce normal ?
|
Oui.
| Quote: | peut-on garder une taille de 8 en utilisant des fonctions virtuelles ?
|
Ben, ça va être dur. Dans un polymorphisme dynamique,
il faut pouvoir, à l'exécution, savoir retrouver le type
réel de l'objet. Et cela demande un peu plus d'info
que sur un typage statique.
Marc Boyer
--
À vélo, prendre une rue à contre-sens est moins dangeureux
que prendre un boulevard dans le sens légal. À qui la faute ?
|
|
| Back to top |
|
 |
Stan Guest
|
Posted: Wed Oct 12, 2005 11:40 am Post subject: Re: sizeof et virtual |
|
|
"Aurélien Barbier-Accary" <nospam_star-shoot_mapson (AT) fr (DOT) st> a écrit dans le
message de news:434ced6a$0$13516$626a14ce (AT) news (DOT) free.fr...
| Quote: | Bonjour,
cout << "sizeof(cA) = " << sizeof(cA) << endl; // => 8
cout << "sizeof(cB) = " << sizeof(cB) << endl; // => 16
est-ce normal ?
peut-on garder une taille de 8 en utilisant des fonctions virtuelles ?
|
Dans quel but as-tu besoin d'avoir cette information ?
En fonction du problème à résoudre, il a surement une méthode plus
adaptée à ton cas.
--
-Stan .
|
|
| Back to top |
|
 |
Jean-Marc Bourguet Guest
|
Posted: Wed Oct 12, 2005 7:12 pm Post subject: Re: sizeof et virtual |
|
|
Aurélien Barbier-Accary <nospam_star-shoot_mapson (AT) fr (DOT) st> writes:
| Quote: | Bonjour,
avant ma question, voici les données :
class cA
{
protected:
double d;
public:
cA(const double& d =0.0) { this->d = d; }
~cA(void) {}
};
class cB
{
protected:
double d;
public:
cB(const double& d =0.0) { this->d = d; }
virtual ~cB(void) {}
};
cout << "sizeof(cA) = " << sizeof(cA) << endl; // => 8
cout << "sizeof(cB) = " << sizeof(cB) << endl; // => 16
est-ce normal ?
|
Oui.
| Quote: | peut-on garder une taille de 8 en utilisant des fonctions
virtuelles ?
|
Ça me semble difficile. S'il y a un membre virtuel, il faut
stocker une information de type. Note qu'il y a des chances
(en particulier si tu ne compiles pas en mode 64 bits)
qu'elle ne prenne pas la taille d'un double, mais que les
contraintes d'alignement fassent que les doubles soient
containts d'avoir une adresse multiple de 8, donc que les
types contenant des doubles aient une taille multiple de 8.
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 |
|
 |
Arnaud Debaene Guest
|
Posted: Wed Oct 12, 2005 9:14 pm Post subject: Re: sizeof et virtual |
|
|
Aurélien Barbier-Accary wrote:
| Quote: | Bonjour,
avant ma question, voici les données :
class cA
{
protected:
double d;
public:
cA(const double& d =0.0) { this->d = d; }
~cA(void) {}
};
class cB
{
protected:
double d;
public:
cB(const double& d =0.0) { this->d = d; }
virtual ~cB(void) {}
};
cout << "sizeof(cA) = " << sizeof(cA) << endl; // => 8
cout << "sizeof(cB) = " << sizeof(cB) << endl; // => 16
est-ce normal ?
Oui : Sur tous les compilateurs courants, le fait d'avoir une fonction |
virtuelle dans une classe signifie que un objet de ce type embarque une
donnée membre cachée "v-ptr" (pour "virtual pointer") qui pointe sur une
description générée par le compilateur du type réel de l'objet (le plus
souvent, cette description est appelée la "v-table" parce qu'elle contient
entre autres choses une table de pointeurs sur les méthodes virtuelles de la
classe). Par contre, ce surcout est fixe et n'augmente pas avec le nombre de
méthodes virtuelles.
| Quote: | peut-on garder une taille de 8 en utilisant des fonctions virtuelles ?
Non. Le plus petit que tu puisse *peut être* obtenir c'est sizeof(double) + |
taille d 'un pointeur, soit 12 sur les machines 32 bits courantes, en jouant
sur les options d'alignement et de padding du compilateur (ce qui dégradera
probablement les performances, si c'est seulement possible). C'est si
important que çà?
Arnaud
|
|
| Back to top |
|
 |
Aurélien Barbier-Accary Guest
|
Posted: Fri Oct 14, 2005 4:33 am Post subject: Re: sizeof et virtual |
|
|
Marc Boyer a écrit :
| Quote: | Aurélien Barbier-Accary <nospam_star-shoot_mapson (AT) fr (DOT) st> a écrit :
est-ce normal ?
Oui.
peut-on garder une taille de 8 en utilisant des fonctions virtuelles ?
Ben, ça va être dur. Dans un polymorphisme dynamique,
il faut pouvoir, à l'exécution, savoir retrouver le type
réel de l'objet. Et cela demande un peu plus d'info
que sur un typage statique.
Marc Boyer
|
Il me semblait bien mais le rêve reste permis ;-p
En fait ce qui me choque plus c'est que la taille ne soit pas 12, je pensais
qu'un pointeur suffisait pour la table virtuelle.
Et je croyais naîvement aussi que pour la classe mère la table virtuelle était
inutile (j'en reste convaincu mais apparemment l'économie n'est pas faite) et
qu'elle n'était utilisée que pour des instances de classes filles.
Merci pour ta réponse.
|
|
| Back to top |
|
 |
Aurélien Barbier-Accary Guest
|
Posted: Fri Oct 14, 2005 4:46 am Post subject: Re: sizeof et virtual |
|
|
Arnaud Debaene a écrit :
| Quote: | Oui : Sur tous les compilateurs courants, le fait d'avoir une fonction
virtuelle dans une classe signifie que un objet de ce type embarque une
donnée membre cachée "v-ptr" (pour "virtual pointer") qui pointe sur une
description générée par le compilateur du type réel de l'objet (le plus
souvent, cette description est appelée la "v-table" parce qu'elle contient
entre autres choses une table de pointeurs sur les méthodes virtuelles de la
classe). Par contre, ce surcout est fixe et n'augmente pas avec le nombre de
méthodes virtuelles.
|
Effectivement, après plusieus tests de définitions de classes (virtuelles ou
pas) contenant des objets virtuels ou pas j'ai vu que la taille augmente de 8
pour chaque virtual.
| Quote: | peut-on garder une taille de 8 en utilisant des fonctions virtuelles ?
Non. Le plus petit que tu puisse *peut être* obtenir c'est sizeof(double) +
taille d 'un pointeur, soit 12 sur les machines 32 bits courantes, en jouant
sur les options d'alignement et de padding du compilateur (ce qui dégradera
probablement les performances, si c'est seulement possible).
|
Comme je l'ai dit dans ma réponse à Marc je m'attendais plus à un surcoût de 4
(un pointeur).
Ca m'étonne un peu que ce ne soit du qu'à un "problème" d'alignement. Ce doit
pourtant être le cas puisque Jean-Marc (merci aussi pour ta réponse) et toi en
avez l'air convaincu.
Saurais-tu où je peux trouver une description complète de la structure d'une
classe virtuelle s'il te plait ?
| Quote: | C'est si important que çà?
|
Oui, car le phénomène se produit en cascade et devient "visiblement" coûteux
pour les grosses structures.
Pour plus de détails, cf ma réponse à Stan :-)
Merci pour toutes ces infos.
Aurélien.
|
|
| Back to top |
|
 |
Aurélien Barbier-Accary Guest
|
Posted: Fri Oct 14, 2005 5:00 am Post subject: Re: sizeof et virtual |
|
|
Stan a écrit :
| Quote: | Dans quel but as-tu besoin d'avoir cette information ?
En fonction du problème à résoudre, il a surement une méthode plus
adaptée à ton cas.
|
Bonjour et merci pour ta réponse,
Dans mon appli je travaille avec des BlobTrees qui sont des arbres CSG enrichis,
c'est-à-dire qu'un objet (3D) est défini par des mélanges, unions, intersections
et différences de primitiives géométriques.
Ces primitives sont composés d'un squelette géométrique et d'une peau implicite
(pour les mélanges).
Chaque squelette est composé de points, vecteurs et quelques grandeurs.
Comme les modèles sont animés, en fait il s'agit de trajectoires, vecteurs
dépendants du temps et grandeurs variables.
Et enfin si je me restreint aux trajectoires j'ai besoin que certaines soient
définies relativement à d'autres (gestion et édition simplifiée) donc j'utilise
beaucoup des compositions de trajectoires, vecteurs et gandeurs.
Si on ajoute à ça le fait que ces modèles sont à niveaux de détails, finalement
la structure est assez importante mais surtout elle ne contient que des objets
qui sont des instances de classes virtuelles (de BlobTrees, de primitives, de
squelettes, des trajectoires, ...).
Et comme ce qui m'intéresse vraiment est de gérer plusieurs objets et de faire
des transformations entre eux...
Bref ça coûte finalement assez cher ces 8+8+...+8 octets en plus pour chaque
virtual.
Je n'y avais jamais trop réfléchi avant mais comme je suis en train de tout
recoder pour avoir une architecture ds mes libs plus propre, je voudrais faire
les choses bien.
Je ne vois pas trop si c'est améliorable finalement.
Aurélien.
|
|
| Back to top |
|
 |
Marc Boyer Guest
|
Posted: Fri Oct 14, 2005 5:43 am Post subject: Re: sizeof et virtual |
|
|
Aurélien Barbier-Accary <nospam_star-shoot_mapson (AT) fr (DOT) st> a écrit :
| Quote: | Marc Boyer a écrit :
Aurélien Barbier-Accary <nospam_star-shoot_mapson (AT) fr (DOT) st> a écrit :
Ben, ça va être dur. Dans un polymorphisme dynamique,
il faut pouvoir, à l'exécution, savoir retrouver le type
réel de l'objet. Et cela demande un peu plus d'info
que sur un typage statique.
Il me semblait bien mais le rêve reste permis ;-p
|
Oui, une machine où on stockerait plus d'une information
par bit ;-)
| Quote: | En fait ce qui me choque plus c'est que la taille ne soit pas 12, je pensais
qu'un pointeur suffisait pour la table virtuelle.
|
Il suffit.
Mais ce sont les "contraintes d'alignements". A priori, tu peux faire
un tableau de ton type, et le compilateur veut que chaque instance
commence à une adresse multiple de 8. Donc, il a besoin que la taille
totale de l'objet soit un multiple de 8.
| Quote: | Et je croyais naîvement aussi que pour la classe mère la table virtuelle était
inutile (j'en reste convaincu mais apparemment l'économie n'est pas faite) et
qu'elle n'était utilisée que pour des instances de classes filles.
|
Oui, mais quand il tombe sur un pointeur A* p, il va devoir lire
*p pour savoir dynamiquement si c'est la mère ou la fille. Donc,
il faut que même dans le cas de la mère, il existe une info qui
dise "je suis la mère".
Marc Boyer
--
À vélo, prendre une rue à contre-sens est moins dangeureux
que prendre un boulevard dans le sens légal. À qui la faute ?
|
|
| Back to top |
|
 |
Marc Boyer Guest
|
Posted: Fri Oct 14, 2005 5:52 am Post subject: Re: sizeof et virtual |
|
|
Aurélien Barbier-Accary <nospam_star-shoot_mapson (AT) fr (DOT) st> a écrit :
| Quote: | Dans quel but as-tu besoin d'avoir cette information ?
En fonction du problème à résoudre, il a surement une méthode plus
adaptée à ton cas.
Dans mon appli je travaille avec des BlobTrees qui sont des arbres CSG enrichis,
c'est-à-dire qu'un objet (3D) est défini par des mélanges, unions, intersections
et différences de primitiives géométriques.
Ces primitives sont composés d'un squelette géométrique et d'une peau implicite
(pour les mélanges).
Chaque squelette est composé de points, vecteurs et quelques grandeurs.
Comme les modèles sont animés, en fait il s'agit de trajectoires, vecteurs
dépendants du temps et grandeurs variables.
Et enfin si je me restreint aux trajectoires j'ai besoin que certaines soient
définies relativement à d'autres (gestion et édition simplifiée) donc j'utilise
beaucoup des compositions de trajectoires, vecteurs et gandeurs.
Si on ajoute à ça le fait que ces modèles sont à niveaux de détails, finalement
la structure est assez importante mais surtout elle ne contient que des objets
qui sont des instances de classes virtuelles (de BlobTrees, de primitives, de
squelettes, des trajectoires, ...).
Et comme ce qui m'intéresse vraiment est de gérer plusieurs objets et de faire
des transformations entre eux...
Bref ça coûte finalement assez cher ces 8+8+...+8 octets en plus pour chaque
virtual.
|
+8 pour chaque virtual ? Normalement, on ne paye ce +8 qu'une fois
il me semble.
| Quote: | Je n'y avais jamais trop réfléchi avant mais comme je suis en train de tout
recoder pour avoir une architecture ds mes libs plus propre, je voudrais faire
les choses bien.
Je ne vois pas trop si c'est améliorable finalement.
|
Ben, les contraintes d'alignement, ça va être difficile de passer
outre. La première chose, c'est de voir si le compilateur propose
plusieurs options pour les structures. Je sais que les x86 accèptent
les accès non alignés (avec perte de perfs), donc peut etre que
ton compilateur sait en tirer partie.
Eventuellement, tu peux non pas stoquer un double mais un
unsigned char t[sizeof double], et ne pas accéder à ta variable,
mais passer par une fonction qui va la recalculer systématiquement.
double getValue(){
double res;
memcpy(&res, t, sizeof(res) );
return res;
}
void setValue(double d){
memcpy(t, &d);
}
Marc Boyer
--
À vélo, prendre une rue à contre-sens est moins dangeureux
que prendre un boulevard dans le sens légal. À qui la faute ?
|
|
| Back to top |
|
 |
Aurélien Barbier-Accary Guest
|
Posted: Fri Oct 14, 2005 6:09 am Post subject: Re: sizeof et virtual |
|
|
Marc Boyer a écrit :
| Quote: | Et je croyais naîvement aussi que pour la classe mère la table virtuelle était
inutile (j'en reste convaincu mais apparemment l'économie n'est pas faite) et
qu'elle n'était utilisée que pour des instances de classes filles.
Oui, mais quand il tombe sur un pointeur A* p, il va devoir lire
*p pour savoir dynamiquement si c'est la mère ou la fille. Donc,
il faut que même dans le cas de la mère, il existe une info qui
dise "je suis la mère".
Marc Boyer
|
oups :-O
exact.
|
|
| Back to top |
|
 |
Aurélien Barbier-Accary Guest
|
Posted: Fri Oct 14, 2005 6:16 am Post subject: Re: sizeof et virtual |
|
|
Marc Boyer a écrit :
| Quote: | Aurélien Barbier-Accary <nospam_star-shoot_mapson (AT) fr (DOT) st> a écrit :
Bref ça coûte finalement assez cher ces 8+8+...+8 octets en plus pour chaque
virtual.
+8 pour chaque virtual ? Normalement, on ne paye ce +8 qu'une fois
il me semble.
|
je me suis mal exprimé, bien sûr qu'on ne paye +8 qu'une fois par objet mais
pour un objet virtuel (pardon pour cet abus de langage) contenant 2 objets
virtuels on paye (logiquement) +24.
Si on répète les appartenances, voila ce que j'entendais par 8+8+...+8
| Quote: | Eventuellement, tu peux non pas stoquer un double mais un
unsigned char t[sizeof double], et ne pas accéder à ta variable,
mais passer par une fonction qui va la recalculer systématiquement.
double getValue(){
double res;
memcpy(&res, t, sizeof(res) );
return res;
}
void setValue(double d){
memcpy(t, &d);
}
|
oui mais là je vais trop perdre en temps.
Ah la la, on veut toujours le beurre, l'argent ... ;-p
Bon, il me semble que je n'ai pas d'autre choix que de me résigner sur ce point
et de bien repenser la structure de mes objets.
Merci pour tes explications et propositions.
Aurélien.
|
|
| Back to top |
|
 |
Marc Boyer Guest
|
Posted: Fri Oct 14, 2005 6:20 am Post subject: Re: sizeof et virtual |
|
|
Aurélien Barbier-Accary <nospam_star-shoot_mapson (AT) fr (DOT) st> a écrit :
| Quote: | Marc Boyer a écrit :
Aurélien Barbier-Accary <nospam_star-shoot_mapson (AT) fr (DOT) st> a écrit :
Bref ça coûte finalement assez cher ces 8+8+...+8 octets en plus pour chaque
virtual.
+8 pour chaque virtual ? Normalement, on ne paye ce +8 qu'une fois
il me semble.
je me suis mal exprimé, bien sûr qu'on ne paye +8 qu'une fois par objet mais
pour un objet virtuel (pardon pour cet abus de langage) contenant 2 objets
virtuels on paye (logiquement) +24.
|
Et oui.
| Quote: | Eventuellement, tu peux non pas stoquer un double mais un
unsigned char t[sizeof double], et ne pas accéder à ta variable,
mais passer par une fonction qui va la recalculer systématiquement.
double getValue(){
double res;
memcpy(&res, t, sizeof(res) );
return res;
}
void setValue(double d){
memcpy(t, &d);
}
oui mais là je vais trop perdre en temps.
Ah la la, on veut toujours le beurre, l'argent ... ;-p
|
Ben, le compromis mémoire/CPU est un très vieil équilibre en info.
| Quote: | Bon, il me semble que je n'ai pas d'autre choix que de me résigner sur ce point
et de bien repenser la structure de mes objets.
|
Ben le polymorphisme dynamique, il faut le payer à un moment ou
à un autre. on peut par exemple décider de stocker le type réel
de l'objet dans un type énuméré (8 bits si tu as moins de 256
types), et de se gérer le polymorphisme à la main.
Mais faut être rigoureux pour pas se planter.
Ca peut peut-être se simplifier à grand coups de templates,
mais je ne me lancerais pas dans ça sans une bonne raison.
Marc Boyer
--
À vélo, prendre une rue à contre-sens est moins dangeureux
que prendre un boulevard dans le sens légal. À qui la faute ?
|
|
| Back to top |
|
 |
Arnaud Debaene Guest
|
Posted: Fri Oct 14, 2005 6:22 am Post subject: Re: sizeof et virtual |
|
|
Aurélien Barbier-Accary wrote:
| Quote: | Saurais-tu où je peux trouver une description complète de la
structure d'une classe virtuelle s'il te plait ?
Dans la doc de ton compilateur : il n'y a pas de représentation standard, ca |
dépend du compilo.
Arnaud
|
|
| Back to top |
|
 |
Aurélien Barbier-Accary Guest
|
Posted: Fri Oct 14, 2005 6:25 am Post subject: Re: sizeof et virtual |
|
|
Marc Boyer a écrit :
| Quote: | Aurélien Barbier-Accary <nospam_star-shoot_mapson (AT) fr (DOT) st> a écrit :
Bon, il me semble que je n'ai pas d'autre choix que de me résigner sur ce point
et de bien repenser la structure de mes objets.
Ben le polymorphisme dynamique, il faut le payer à un moment ou
à un autre. on peut par exemple décider de stocker le type réel
de l'objet dans un type énuméré (8 bits si tu as moins de 256
types), et de se gérer le polymorphisme à la main.
Mais faut être rigoureux pour pas se planter.
Ca peut peut-être se simplifier à grand coups de templates,
mais je ne me lancerais pas dans ça sans une bonne raison.
|
Merci pour les pistes, il faut que j'y réfléchisse...
|
|
| 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
|
|