Bonsoir ^_^,

Je ne savais pas où mettre ce message, j'ai hésité avec la rubrique "Contribuez", mais ce n'est pas vraiment de moi =). J'ai trouvé cette astuce sur un blog et je vous la partage car je la trouve très utile. Par contre, elle ne fonctionne que sous Visual.

Vous n'êtes sûrement pas sans savoir que, afin de minimiser l'espace mémoire, les variables membres d'une classe ou d'une structure doivent être organisées suivant un ordre précis afin d'éviter de créer des "paddings" inutiles. J'imagine que le compilateur est suffisamment intelligent pour pouvoir réorganiser lui-même les variables (quelqu'un pourrait confirmer ou infirmer ?), mais c'est toujours mieux de le faire soi-même.

Concrètement, voici une structure qui illustre ce soucis :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
struct Test
{
    char a; // 1 octet
    int b; // 4 octets
    char c; // 1 octet
    int d; // 4 octets
};
Puisque l'alignement se fait sur 4 octets, le compilateur va donc automatiquement ajouter un padding de 3 octets entre la variable a et b, et 3 autres entre c et d, ce qui donnera en fait ceci :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
struct Test
{
    char a; // 1 octet
    char pad[3]; // 3 octets
    int b; // 4 octets
    char c; // 1 octet
    char pad2[3]; // 3 octets
    int d; // 3 octets
};
On a donc, dans cette structure, 6 octets qui sont gâchés. Il est parfois assez chiant de devoir compter soi-même pour réorganiser les données, et en fait, il existe un warning à activer qui permet de lever un warning automatiquement pour indiquer ça. C'est bizarre car même avec le warning niveau 4 il n'est pas activé.

L'astuce consiste en encadrer la structure par #pragma warning(error: 4820) et #pragma warning(disable: 4820), ce qui donne :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
#pragma warning(error: 4820)
struct Test
{
			char a; // 1 octet
                        int b; // 4 octets
                        char c; // 1 octet
                        int d; // 4 octets
};
#pragma warning(disable: 4820)
Et le compilateur lève le warning suivant :

'Test' : '3' bytes padding added after data member 'Test::a'
'Test' : '3' bytes padding added after data member 'Test::c'

On sait donc immédiatement ou le padding est ajouté, et on peut donc réorganiser la structure comme ceci :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
struct Test
{
    int b; // 4 octets
    int d; // 4 octets
   char a; // 1 octet
   char c; // 1 octet
   char pad[2]; // 2 octets
};
Et hop ! Au lieu de perdre 6 octets sur la structure on n'en perd que deux =). Je sais très bien que c'est le genre de micro-optimisation qui ne va pas changer grand chose en terme de performances, mais c'est tellement simple à réorganiser que je vois pas pourquoi on s'en priverait On peut ensuite enlever les #pragma et aller tester une autre classe.