Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Taille de classe

32 réponses
Avatar
Lucas Levrel
Bonjour,

Si une classe A contient un champ de type T, est-il garanti que sizeof(A)
sera un multiple entier de sizeof(T) ?

Par exemple, si je définis
class A {
int un;
double deux;
}
(ou double d'abord et int ensuite) et que je compile avec le compilateur
Intel, j'obtiens sizeof(A)==16 (sachant que sizeof(int)==4 et
sizeof(double)==8). Est-ce imposé par la norme ? Est-ce un comportement
général des compilateurs courants ?

--
LL

10 réponses

1 2 3 4
Avatar
Alain Ketterlin
Lucas Levrel writes:

Si une classe A contient un champ de type T, est-il garanti que
sizeof(A) sera un multiple entier de sizeof(T) ?

Par exemple, si je définis
class A {
int un;
double deux;
}
(ou double d'abord et int ensuite) et que je compile avec le
compilateur Intel, j'obtiens sizeof(A)= (sachant que sizeof(int) ==4
et sizeof(double)==8). Est-ce imposé par la norme ? Est-ce un
comportement général des compilateurs courants ?



Si mes souvenirs sont bons, la règle est que les champs soient align és
sur un multiple de leur taille. Dans ton exemple, il y a donc un padding
entre un et deux, pour que le double soit aligné sur un multiple de 8.
Si tu changes l'ordre, tu devrais arriver à 12.

-- Alain.
Avatar
Lucas Levrel
Le 4 octobre 2012, Alain Ketterlin a écrit :

Si mes souvenirs sont bons, la règle est que les champs soient alignés
sur un multiple de leur taille. Dans ton exemple, il y a donc un padding
entre un et deux, pour que le double soit aligné sur un multiple de 8.
Si tu changes l'ordre, tu devrais arriver à 12.



Merci. J'obtiens 16 quel que soit l'ordre : peut-être parce qu'il faut
pouvoir faire des vecteurs dont chaque élément est aligné ?

--
LL
Avatar
Jean-Marc Bourguet
Lucas Levrel writes:

Le 4 octobre 2012, Alain Ketterlin a écrit :

Si mes souvenirs sont bons, la règle est que les champs soient alig nés
sur un multiple de leur taille. Dans ton exemple, il y a donc un padding
entre un et deux, pour que le double soit aligné sur un multiple de 8.
Si tu changes l'ordre, tu devrais arriver à 12.



Merci. J'obtiens 16 quel que soit l'ordre : peut-être parce qu'il fa ut
pouvoir faire des vecteurs dont chaque élément est aligné ?



Oui. Une struct est au moins autant alignee que le plus aligne de ses
membres.

(Il y a des machines ou ne pas respecter l'alignement cause des crashs,
d'autres ou ce n'est qu'un probleme potentiel -- il peut y avoir
d'autres conditions -- de perf).

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
Avatar
Lucas Levrel
Le 4 octobre 2012, Jean-Marc Bourguet a écrit :

Oui. Une struct est au moins autant alignee que le plus aligne de ses
membres.



Merci !

--
LL
Avatar
Marc Boyer
Le 04-10-2012, Lucas Levrel a écrit :
Bonjour,

Si une classe A contient un champ de type T, est-il garanti que sizeof(A)
sera un multiple entier de sizeof(T) ?

Par exemple, si je définis
class A {
int un;
double deux;
}
(ou double d'abord et int ensuite) et que je compile avec le compilateur
Intel, j'obtiens sizeof(A)= (sachant que sizeof(int)==4 et
sizeof(double)==8). Est-ce imposé par la norme ? Est-ce un comportement
général des compilateurs courants ?



J'ai pas la norme en tête, mais les compilos ont deux contraintes:
1) respecter l'ordre des champs dans la déclaration
2) respecter des contraintes d'alignement, qui permettent de faire des
tableaux contigus

Donc, on va avoir un A aligné sur le plus contraint de ses membres
(sachant que si on a des fonctions virtuelles, le compilo va surement
ajouter un pointeur quelque part dans A).

Mais alignement et taille sont distincts:
#include <iostream>

class A {
public:
char x[5];
char y[3];
};

int main(){
std::cout<<sizeof(A::x)<<std::endl;
std::cout<<sizeof(A::y)<<std::endl;;
std::cout<<sizeof(A)<<std::endl;;
}

Avec mon g++, j'ai 5, 3 et 8. Et 8 n'est ni multiple de 5 ou 3.

Marc Boyer
--
À mesure que les inégalités regressent, les attentes se renforcent.
François Dubet
Avatar
Lucas Levrel
Le 5 octobre 2012, Marc Boyer a écrit :

#include <iostream>

class A {
public:
char x[5];
char y[3];
};

int main(){
std::cout<<sizeof(A::x)<<std::endl;
std::cout<<sizeof(A::y)<<std::endl;;
std::cout<<sizeof(A)<<std::endl;;
}

Avec mon g++, j'ai 5, 3 et 8. Et 8 n'est ni multiple de 5 ou 3.



Ah oui, je n'avais pas pensé aux types tableaux (qui reviennent à
multiplier le type de base). Dans mon cas j'ai effectivement des tableaux
dans la classe, « cachés » par un typedef qui plus est, mais heureusement
je n'ai besoin que de la multiplicité par rapport au type de base.

--
LL
Avatar
Benoit Izac
Bonjour,

le 04/10/2012 à 12:53, Lucas Levrel a écrit dans le message
:

Si une classe A contient un champ de type T, est-il garanti que
sizeof(A) sera un multiple entier de sizeof(T) ?

Par exemple, si je définis
class A {
int un;
double deux;
}
(ou double d'abord et int ensuite) et que je compile avec le
compilateur Intel, j'obtiens sizeof(A)= (sachant que sizeof(int)==4
et sizeof(double)==8). Est-ce imposé par la norme ? Est-ce un
comportement général des compilateurs courants ?



Quel est l'intérêt de connaître la taille d'une classe ?
Quel est l'intérêt d'utiliser une classe sans méthode plutôt qu'une
structure ?

--
Benoit Izac
Avatar
Alain Ketterlin
Benoit Izac writes:

le 04/10/2012 à 12:53, Lucas Levrel a écrit dans le message
:

Si une classe A contient un champ de type T, est-il garanti que
sizeof(A) sera un multiple entier de sizeof(T) ?

Par exemple, si je définis
class A {
int un;
double deux;
}
(ou double d'abord et int ensuite) et que je compile avec le
compilateur Intel, j'obtiens sizeof(A)= (sachant que sizeof(int) ==4
et sizeof(double)==8). Est-ce imposé par la norme ? Est-ce un
comportement général des compilateurs courants ?



Quel est l'intérêt de connaître la taille d'une classe ?



Tu veux sûrement dire la taille des instances ? Je ne pense pas que ce
soit la taille en soi qui intéresse Lucas, mais plutôt la fragmen tation
induite par l'ordre et l'alignement des champs. Celui qui écrit :

struct s {
int x
double y;
int z;
};

paye 24 octets pour 16 utiles (sur une configuration fréquente). Cela
peut vite s'accumuler si tu imbriques beaucoup. Par exemple, pour

struct t {
s s1;
s s2;
};

mon g++ 4.6.3 m'annonce 48 octets. Et si tu as beaucoup d'objets (dans
des tableaux/vecteurs par exemple), cela peut commencer à chiffrer. Ca
remplit la mémoire, les caches, etc.

Quel est l'intérêt d'utiliser une classe sans méthode plut ôt qu'une
structure ?



Fournir un exemple minimal qui illustre son propos, j'imagine. Rien
d'autre, pas de panique, ce n'est manifestement pas du code de
production, de toute façon il manque le point-virgule.

-- Alain.
Avatar
Benoit Izac
Bonjour,

le 05/10/2012 à 22:08, Alain Ketterlin a écrit dans le message
:

Quel est l'intérêt de connaître la taille d'une classe ?



Tu veux sûrement dire la taille des instances ?



L'exemple de Marc n'utilise pas d'instance.

Je ne pense pas que ce soit la taille en soi qui intéresse Lucas, mais
plutôt la fragmentation induite par l'ordre et l'alignement des
champs. Celui qui écrit :

struct s {
int x
double y;
int z;
};

paye 24 octets pour 16 utiles (sur une configuration fréquente). Cela
peut vite s'accumuler si tu imbriques beaucoup. Par exemple, pour

struct t {
s s1;
s s2;
};

mon g++ 4.6.3 m'annonce 48 octets. Et si tu as beaucoup d'objets (dans
des tableaux/vecteurs par exemple), cela peut commencer à chiffrer. Ca
remplit la mémoire, les caches, etc.



Je comprends le problème pour les structures (ça a été discuté dans fclc
il y a quelques temps). En revanche, ne connaissant pas C++, je me dis
qu'il doit y avoir une raison pour choisir un classe plutôt qu'une
structure.

À ce propos, à chaque fois qu'une instance est crée, est-ce que le code
des méthodes est dupliqué ?

Quel est l'intérêt d'utiliser une classe sans méthode plutôt qu'une
structure ?



Fournir un exemple minimal qui illustre son propos, j'imagine. Rien
d'autre, pas de panique, ce n'est manifestement pas du code de
production, de toute façon il manque le point-virgule.



Je ne panique pas. ;-)

--
Benoit Izac
Avatar
Alain Ketterlin
Benoit Izac writes:

le 05/10/2012 à 22:08, Alain Ketterlin a écrit dans le message
:

Quel est l'intérêt de connaître la taille d'une classe ?



Tu veux sûrement dire la taille des instances ?



L'exemple de Marc n'utilise pas d'instance.



sizeof() renseigne sur la taille des instance.

[...]
À ce propos, à chaque fois qu'une instance est crée, est-c e que le code
des méthodes est dupliqué ?



Non non, le code est là une fois pour toute.

-- Alain.
1 2 3 4