OVH Cloud OVH Cloud

supression d'un private...

58 réponses
Avatar
Stan
Une reflexion à propos de la question posée précédemment sur
l'incidence de la supression d'un private dans un source.

La question d'origine était : Est-ce que le fait de supprimer
un ou plusieurs "private" peut modifier le comportement du programme ?

Dans le cas en question, sans doute pas, mais il est des cas...
Par exemple en modifiant le type d"héritage.

La plupart des compilateurs utilisent l'EBO ( Empty Base Optimization ), et
il
s'avère que dans le cas d'un héritage privé d'une classe vide :
class Nutshell { };
, l'EBO peut s'effectuer. Donc, dans la pratique, la taille du code généré
peut varier
selon le type d'héritage ( ...d'une classe vide ).

En résumé,
class A : private Nutshell
{
private:
int Value;
};

peut avoir une taille différente de :
class A : public Nutshell
{
private:
int Value;
};

Si le code effectue des tests sur la taille de la classe :
if( sizeof( A ) > otherclass ) ... //
cela peut modifier le comportement du programme à l'execution !

Je sais, c'est tordu ;-)
Et d'ailleurs, mon raisonnement est-il correct ?

--
-Stan

10 réponses

1 2 3 4 5
Avatar
Arnaud Meurgues
Stan wrote:

Si le code effectue des tests sur la taille de la classe :
if( sizeof( A ) > otherclass ) ... //
cela peut modifier le comportement du programme à l'execution !

Je sais, c'est tordu ;-)
Et d'ailleurs, mon raisonnement est-il correct ?


De toute façon, la taille d'une classe n'est pas garantie par la norme.
Par conséquent, ce genre de code n'est pas portable, ni déterministe (à
par avec une version donnée d'un compilateur sur une plateforme donnée,
à la rigueur).
Donc, il ne faut pas s'étonner si son comportement varie en fonction du
vent et de la pluie, non ?

--
Arnaud

Avatar
Loïc Joly
Une reflexion à propos de la question posée précédemment sur
l'incidence de la supression d'un private dans un source.

La question d'origine était : Est-ce que le fait de supprimer
un ou plusieurs "private" peut modifier le comportement du programme ?

Dans le cas en question, sans doute pas, mais il est des cas...
Par exemple en modifiant le type d"héritage.

La plupart des compilateurs utilisent l'EBO ( Empty Base Optimization ), et
il
s'avère que dans le cas d'un héritage privé d'une classe vide :
class Nutshell { };
, l'EBO peut s'effectuer.


Qu'est-ce qui empêche l'EBO de s'appliquer pour de l'héritage public ?

--
Loïc

Avatar
Bertrand Lenoir-Welter
Stan :

Si le code effectue des tests sur la taille de la classe :
if( sizeof( A ) > otherclass ) ... //
cela peut modifier le comportement du programme à l'execution !


Si ma tante en avait...


Je sais, c'est tordu ;-)


Me voilà rassuré. Etes-vous prêt à déclarer sur l'honneur que vous
seriez capable de coder un truc comme ça dans un programme sérieux ?


Et d'ailleurs, mon raisonnement est-il correct ?


Je ne vois guère que deux int à comparer... Mais ça doit dépendre de
l'humeur du compilo ou plutôt de ceux qui l'ont réalisé. J'avoue n'avoir
probablement jamais eu à utiliser un sizeof global pour une classe. Mais
je vais quand même essayer sur le mien, tenez !

Avatar
Stan
"Arnaud Meurgues" a écrit dans le
message de news: 4329333f$0$1918$
Stan wrote:

Si le code effectue des tests sur la taille de la classe :
if( sizeof( A ) > otherclass ) ... //
cela peut modifier le comportement du programme à l'execution !

Je sais, c'est tordu ;-)
Et d'ailleurs, mon raisonnement est-il correct ?


De toute façon, la taille d'une classe n'est pas garantie par la norme.


Y a quand même des évidences :

class A{
char x;
};

class B{
int x;
long z;
long v;
long u;
};

if( sizeof( B) > sizeof( A) ) std::cout << "oops" << endl;


Par conséquent, ce genre de code n'est pas portable, ni déterministe (à
par avec une version donnée d'un compilateur sur une plateforme donnée,
à la rigueur).


La portabilité n'est pas toujours un pré-requis.

Donc, il ne faut pas s'étonner si son comportement varie en fonction du
vent et de la pluie, non ?


Exagérer n'a jamais rendu plus crédible.

--
-Stan


Avatar
Fabien LE LEZ
On Thu, 15 Sep 2005 12:14:09 +0200, "Stan" (
remove the dots )>:

De toute façon, la taille d'une classe n'est pas garantie par la norme.


Y a quand même des évidences :


Pour les POD, je crois que la situation est différente.

Et de toutes façons, la norme est une chose, les implémentations
usuelles, une autre.

Pour prendre l'exemple classique, jusqu'à assez récemment, la norme
n'imposait pas que les éléments d'un vector<> soient contigus,
pourtant c'était le cas dans toutes les implémentations.


Avatar
kanze
Fabien LE LEZ wrote:
On Thu, 15 Sep 2005 12:14:09 +0200, "Stan"
( remove the dots )>:

De toute façon, la taille d'une classe n'est pas garantie
par la norme.


Y a quand même des évidences :


Pour les POD, je crois que la situation est différente.


Oui et non. Dans la mesure où les POD doivent être compatible
avec le C, et qu'en C, on a la notion des types compatible,
peut-être.

En revanche, la taille d'un POD peut bien varier selon les
options de compilation, sans parler de la version du
compilateur, le compilateur même, et la machine.

Et de toutes façons, la norme est une chose, les
implémentations usuelles, une autre.


Toutes les implémentations que je connais ont des options pour
varier le packing.

Pour prendre l'exemple classique, jusqu'à assez récemment, la
norme n'imposait pas que les éléments d'un vector<> soient
contigus, pourtant c'était le cas dans toutes les
implémentations.


C'est un autre problème. Même aujourd'hui, la norme permet du
rembourrage entre des différents membres d'une classe, et dans
la pratique, les compilateurs varient en ce qui concerne leur
politique là-dessus.

--
James Kanze GABI Software
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
Stan ( remove the dots ) wrote:
Une reflexion à propos de la question posée précédemment sur
l'incidence de la supression d'un private dans un source.

La question d'origine était : Est-ce que le fait de supprimer
un ou plusieurs "private" peut modifier le comportement du
programme ?

Dans le cas en question, sans doute pas, mais il est des
cas... Par exemple en modifiant le type d"héritage.

La plupart des compilateurs utilisent l'EBO ( Empty Base
Optimization ), et il s'avère que dans le cas d'un héritage
privé d'une classe vide :

class Nutshell { };
, l'EBO peut s'effectuer.


De même que dans le cas d'un héritage public.

Donc, dans la pratique, la taille du code généré peut varier
selon le type d'héritage ( ...d'une classe vide ).


C'est aussi peu probable que de faire dépendre le EBO sur la
première lettre du nom de la classe : on l'applique si le nom de
la classe commence par un majuscule, non si c'est un minuscule.
C'est permis, mais je vois mal une implémentation le faire.

--
James Kanze GABI Software
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
Arnaud Meurgues
Stan wrote:

Par conséquent, ce genre de code n'est pas portable, ni déterministe (à
par avec une version donnée d'un compilateur sur une plateforme donnée,
à la rigueur).
La portabilité n'est pas toujours un pré-requis.



Non. Mais le déterminisme est préférable.

Donc, il ne faut pas s'étonner si son comportement varie en fonction du
vent et de la pluie, non ?
Exagérer n'a jamais rendu plus crédible.



La muflerie non plus.

--
Arnaud


Avatar
Stan
"Arnaud Meurgues" a écrit dans le
message de news: 432a8517$0$7948$
Stan wrote:

Par conséquent, ce genre de code n'est pas portable, ni déterministe (à
par avec une version donnée d'un compilateur sur une plateforme donnée,
à la rigueur).
La portabilité n'est pas toujours un pré-requis.



Non. Mais le déterminisme est préférable.

Donc, il ne faut pas s'étonner si son comportement varie en fonction du
vent et de la pluie, non ?
Exagérer n'a jamais rendu plus crédible.



La muflerie non plus.


L'éxagération est une habitude chez toi.


--
-Stan



Avatar
Bertrand Lenoir-Welter
Pour info, j'ai essayé la chose suivante (Borland C++ 5.02) :

class C1: public C0
{
public:
int i;
};

class C2: private C0
{
public:
int i;
};

class C3: public C0
{
private:
int i;
};

class C4: private C0
{
private:
int i;
};

sizeof(Cn) me renvoie la même taille (C0 + int) dans les 4 cas.

Je suis pas allé voir dans l'assembleur pour chercher d'éventuelles
différences, mais je parie une boîte de cassoulet qu'y'en a pas.
1 2 3 4 5