OVH Cloud OVH Cloud

help problème sizeof struct !!!

13 réponses
Avatar
Vincent
bonjour,

Voici mon problème :

soient :

struct S1
{
int toto;
}mytruc;

struct S2
{
short titi;
}mytruc2;

struct S3
{
int toto;
short titi;
}mytruc3

sizeof(S1) donne 4;
sizeof(S2) donne 2;
sizeof(S3) donne 8 ?????!!!!!

Où est l'erreur ?

quand je fait un read dans un fichier avec S3, çà donne forcement un truc
bizare ?

une idée ?

merci

Vincent

3 réponses

1 2
Avatar
kanze
Fabien LE LEZ wrote:
On 24 Nov 2005 00:03:25 -0800, "kanze" :

Dans la pratique, je vais ignorer les problèmes des
différentes tailles de byte, jusqu'au jour où je ne le peux
pas. Qui n'arrivera probablement jamais.


Idem. En fait, je considère (peut-être à tort) que CHAR_BIT
est systématiquement 8 sur toutes les machines concernées par
mon code (Pour l'instant, c'est des machines compatibles i386,
donc je ne cours pas trop de risques ;-) )


La risque est en effet faible.

Néanmoins, j'utilise CHAR_BIT parce que "8" est une "magic
value".


Mais CHAR_BIT est une valeur fausse, dans ce sens. Comme j'ai
dit, il précise d'autre chose que ce qu'on veut. C'est vrai que
dans prèsque tous les cas, les deux valeurs seront identique,
mais c'est quand même pas la même chose. Si tu tiens à ne pas te
servir de 8 directement (ce qu'on peut comprendre), il faudrait
définir une constante qui convient, disons OCTET_BIT. Seulement
alors, quelle est la différence entre utiliser OCTET_BIT, EIGHT
ou 8.

Si je veux autre chose que 8, c'est qu'il s'agit d'un autre
protocol, et que mon code n'est de toute façon pas utilisable.
Dans ce cas-ci, je me sers effectivement des nombres
«@magiques@» directement dans le code. De même que par exemple
7, s'il s'agit de nombre de jours dans la semaine. Il ne faut
pas appliquer des règles à l'aveugle. Il y a deux grands buts
dans l'utilisation des constantes symboliques. Le premier, c'est
de pouvoir les modifier, si la valeur change, sans avoir à
régarder tous les 8 dans le code, pour voir lesquels
correspondent à la valeur à changer, et lesquels non, et
l'autre, c'est pour facilité la lecture, pour que d'autres
programmeurs sachent ce que c'est la valeur. Or, le nombre de
bits dans un octet ou le nombre de jours dans la semaine sont
des valeurs qui ne peuvent pas changer ; elles sont fixées en
dehors de ton programme pour tout le temps. Alors, si la
contexte rend évident la signification, je ne vois pas l'intérêt
de la constante symbolique. Dans mon code réel, j'ai donc :

void
MD5::appendWord(
Word word )
{
(*this) += static_cast< GB_uint8_t >( word ) ;
(*this) += static_cast< GB_uint8_t >( word >> 8 ) ;
(*this) += static_cast< GB_uint8_t >( word >> 16 ) ;
(*this) += static_cast< GB_uint8_t >( word >> 24 ) ;
}

Il y a trois « valeurs magiques », si tu veux. Mais est-ce que
la lisibilité en serait réelement accrue si j'utilisais
shiftCountByte1, shiftCountByte2, etc., ou byteShiftCount*1,
byteShiftCount*2, etc. ? (Je n'en est pas l'impression, mais
c'est évidemment un point de vue, et non un fait objectif.)

--
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
wrote:

Dans la pratique, je vais ignorer les problèmes des
différentes tailles de byte, jusqu'au jour où je ne le peux
pas. Qui n'arrivera probablement jamais.


Avec un petit static_assert ?


En général non, sauf qu'il y a manifestement une dépendance. Je
n'ai pas accès à une machine avec des char de 9 bits ; je n'en
ai pas eu accès depuis très longtemps, bien avant que j'ai
commencé à faire du C. C'est un cas assez spécial, et je pars du
principe que mon code n'y fonctionnera pas ; je n'ai aucune
expérience réele sur laquelle me baser pour savoir quels sont
les choses auxquelles il faut faire attention.

--
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
Fabien LE LEZ wrote:
On Thu, 24 Nov 2005 09:44:03 -0500, "Eric Pruneau"
:

#pragma pack(1)

Note: Ceci marche bien avec VC++, je sais pas trop avec un
autre compilateur


Je confirme que les "#pragma" sont totalement dépendants du
compilateur.

Si un compilo ne comprend pas une directive #pragma, il
l'ignorera tout simplement (avec éventuellement un warning).

Le danger peut résider dans le fait qu'une directive #pragma
donnée puisse vouloir dire une chose sur un compilateur et
tout à fait autre chose sur un autre compilateur, mais je n'ai
pas encore rencontré ce cas.


Avec combien de compilateurs, sur combien de plateformes ?

Sérieusement, je crois qu'avec pack, la seule risque que tu
cours, c'est qu'il soit ignoré. Seulement, si on peut l'ignorer
sans que le programme soit en erreur, pourquoi est-ce qu'on s'en
sert ?

En passant, je confirmerai que et g++ et Sun CC comprend pack.

--
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


1 2