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

structure et padding

8 réponses
Avatar
Laurent Deniau
Existe-t-il des cas (des architectures) ou les deux structures
ci-dessous n'auraient pas le meme "layout", c'est-a-dire que l'une
aurait du padding entre les champs a et f que l'autre n'aurait pas:

struct A {
void *p;
unsigned a;
void (*f)(void);
}

struct B {
struct B_ {
void *p;
unsigned a;
} b;
void (*f)(void);
}

J'ai essaye toutes les combinaisons de tailles imaginable, et il me
semble qu'il faudrait une architecture tres bizarre pour avoir du
padding entre a et f. Quelque chose du genre:

void* sur 4 mais avec alignement sur 2 avec un unsigned sur 2
(alignement sur 2) et un (*)() sur 4 avec alignement sur 4. Cela
donnerait un padding de 2.

void* sur 2 (alignement sur 2) avec un unsigned sur 4 mais avec
alignement sur 2 et un (*)() sur 4 avec alignement sur 4. Cela donnerait
un padding de 2.

etc...

Le petit programme ci-dessous calcule le padding entre a et f. Mais il
me renvoie toujours zero sur les architectures que j'ai sous la main
(IA32, sparc). Est-ce que qqun peut l'essayer sur des architectures ou
des modeles memoires exotiques et me dire s'il obtient autre chose que
zero? Merci.

a+, ld.

#include <stdio.h>
#include <stddef.h>

struct A {
void *p;
unsigned a;
void (*f)(void);
};

struct B {
struct B_ {
void *p;
unsigned a;
} b;
void (*f)(void);
};

int main(void)
{
int diff = offsetof(struct B,f) - offsetof(struct A,f);

printf("padding = %d\n", diff);

return 0;
}

8 réponses

Avatar
Pierre Maurette
[...]
Sous XP Pro x64:

padding = 0
sizeof(unsigned) = 4
sizeof(void*) = 8

VC++ 8.0 Beta, en C:
Microsoft (R) C/C++ Optimizing Compiler Version 14.00.40904 for x64
Microsoft (R) Incremental Linker Version 8.00.40904

Je le passerai sou Gcc en X86-64 quand je rebooterai

--
Pierre
Avatar
Harpo
Pierre Maurette wrote:

Microsoft (R) Incremental Linker Version 8.00.40904

Je le passerai sou Gcc en X86-64 quand je rebooterai


Prudence est mère de la sureté.

Avatar
Pierre Maurette
[...]
Sous Debian 64:

padding = 0
sizeof(unsigned) = 4
sizeof(void*) = 8

gcc 3.4
Avatar
Jean-Marc Bourguet
Laurent Deniau writes:

Existe-t-il des cas (des architectures) ou les deux structures ci-dessous
n'auraient pas le meme "layout", c'est-a-dire que l'une aurait du padding
entre les champs a et f que l'autre n'aurait pas:

struct A {
void *p;
unsigned a;
void (*f)(void);
}

struct B {
struct B_ {
void *p;
unsigned a;
} b;
void (*f)(void);
}


Il me semble que
- unsigned sur 2 bytes avec alignement sur 2,
- void* sur 4 bytes avec alignement sur 4,
- (*f)() sur 2 bytes avec aligne,ent sur 2
est ce que tu cherches. Le modèle pour x86 avec plusieurs
segments de données mais un seul segment de code est donc un
candidat (je ne me souviens ni du nom ni de l'alignement de
ce modèle et je ne suis qu'à moitié sur de la taille des unsigned).

A+

--
Jean-Marc
FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Pierre Maurette
[...]
Il me semble que
- unsigned sur 2 bytes avec alignement sur 2,
- void* sur 4 bytes avec alignement sur 4,
- (*f)() sur 2 bytes avec aligne,ent sur 2
est ce que tu cherches. Le modèle pour x86 avec plusieurs
segments de données mais un seul segment de code est donc un
candidat (je ne me souviens ni du nom ni de l'alignement de
ce modèle et je ne suis qu'à moitié sur de la taille des unsigned).
En x86, il y a également des pointeurs sur 6 bytes, 16:32, les FAR32 de

MASM. Mais je suis bien infoutu de faire le rapport avec C.

--
Pierre

Avatar
Jean-Marc Bourguet
"Pierre Maurette" writes:

[...]
Il me semble que
- unsigned sur 2 bytes avec alignement sur 2,
- void* sur 4 bytes avec alignement sur 4,
- (*f)() sur 2 bytes avec aligne,ent sur 2
est ce que tu cherches. Le modèle pour x86 avec plusieurs
segments de données mais un seul segment de code est donc un
candidat (je ne me souviens ni du nom ni de l'alignement de
ce modèle et je ne suis qu'à moitié sur de la taille des unsigned).
En x86, il y a également des pointeurs sur 6 bytes, 16:32, les FAR32 de

MASM. Mais je suis bien infoutu de faire le rapport avec C.


Je ne connais pas de système où l'utilisation de tels
pointeurs a du sens. Peut-être avec certains DOS-Extender
(domaine que je n'ai jamais bien connu, celui que j'ai
utilisé fonctionnait en mode "flat"), ou bien des OS plus ou
moins étrange.

A+

--
Jean-Marc
FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc
Site de usenet-fr: http://www.usenet-fr.news.eu.org


Avatar
bernard tatin
"Pierre Maurette" writes:


[...]

Il me semble que
- unsigned sur 2 bytes avec alignement sur 2,
- void* sur 4 bytes avec alignement sur 4,
- (*f)() sur 2 bytes avec aligne,ent sur 2
est ce que tu cherches. Le modèle pour x86 avec plusieurs
segments de données mais un seul segment de code est donc un
candidat (je ne me souviens ni du nom ni de l'alignement de
ce modèle et je ne suis qu'à moitié sur de la taille des unsigned).


En x86, il y a également des pointeurs sur 6 bytes, 16:32, les FAR32 de
MASM. Mais je suis bien infoutu de faire le rapport avec C.



Je ne connais pas de système où l'utilisation de tels
pointeurs a du sens. Peut-être avec certains DOS-Extender
(domaine que je n'ai jamais bien connu, celui que j'ai
utilisé fonctionnait en mode "flat"), ou bien des OS plus ou
moins étrange.

A+

Pour moi, cela n'est utilisé que dans les DOS extenders. Les modèles de

compilation fournis par le compilateur Watcom (devenu OpenWatcom)
doivent permettre l'accès à ces types de pointeurs. La dernière fois que
j'ai utilisé ça, c'est il y a environ 10 ans. Je ne me souviens plus des
détails.

Bernard



Avatar
Laurent Deniau
Jean-Marc Bourguet wrote:
Laurent Deniau writes:


Existe-t-il des cas (des architectures) ou les deux structures ci-dessous
n'auraient pas le meme "layout", c'est-a-dire que l'une aurait du padding
entre les champs a et f que l'autre n'aurait pas:

struct A {
void *p;
unsigned a;
void (*f)(void);
}

struct B {
struct B_ {
void *p;
unsigned a;
} b;
void (*f)(void);
}



Il me semble que
- unsigned sur 2 bytes avec alignement sur 2,
- void* sur 4 bytes avec alignement sur 4,
- (*f)() sur 2 bytes avec aligne,ent sur 2
est ce que tu cherches. Le modèle pour x86 avec plusieurs
segments de données mais un seul segment de code est donc un
candidat (je ne me souviens ni du nom ni de l'alignement de
ce modèle et je ne suis qu'à moitié sur de la taille des unsigned).


Oui, c'est bien a ca que je pensais. Je crois que c'etait le modele
"compact" si mes souvenir sont bons.

Neanmoins (reflexion sur les propos de b. Tatin) les dinosaures qui
proposaient ces modeles de memoire n'etait pour la pluspart non conforme
a C89. Or mon code necessite un tres tres bonne conformance a C89 sinon
il ne compile pas.

Sinon j'ai ajoute un void* juste apres a, ce qui resoud tous les
problemes d'alignement sur tous les modeles de memoire. Note que je l'ai
fait parce que j'ai trouve une utilite a ce champ supplementaire, pas
seulement pour evider de gerer les problemes d'alignement ;-)

J'en profite pour remercier ceux qui mon repondu.

a+, ld.