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

problème avec struct.calcsize qui retourne la même valeur alors qu'un entier non signé a été ajouté au for matage

3 réponses
Avatar
pata...
bonjour,

je rencontre un comportement étrange de la part de la fonction calcsize du module struct.

voici le problème :
# 8<-----------
cd /tmp/
python --version
Python 3.10.1
python -m venv struct.test
source struct.test/bin/activate
python -c 'import struct; print(struct.calcsize("4sIQ4I2Q"), 4+4+8+(4*4)+(2*8))'
48 48
python -c 'import struct; print(struct.calcsize("4sIQ5I2Q"), 4+4+8+(5*4)+(2*8))'
56 52
python -c 'import struct; print(struct.calcsize("4sIQ6I2Q"), 4+4+8+(6*4)+(2*8))'
56 56
# 8<-----------

struct.calcsize("4sIQ5I2Q") ne retourne pas 52 comme attendu...

une explication ?

cordialement, lacsaP.

3 réponses

Avatar
Benoit Izac
Bonjour,
Le 04/02/2022 Í  16:29, "" a écrit
dans le message
 :
je rencontre un comportement étrange de la part de la fonction
calcsize du module struct.
voici le problème :
# 8<-----------
cd /tmp/
python --version
Python 3.10.1
python -m venv struct.test
source struct.test/bin/activate
python -c 'import struct; print(struct.calcsize("4sIQ4I2Q"), 4+4+8+(4*4)+(2*8))'
48 48
python -c 'import struct; print(struct.calcsize("4sIQ5I2Q"), 4+4+8+(5*4)+(2*8))'
56 52
python -c 'import struct; print(struct.calcsize("4sIQ6I2Q"), 4+4+8+(6*4)+(2*8))'
56 56
# 8<-----------
struct.calcsize("4sIQ5I2Q") ne retourne pas 52 comme attendu...
une explication ?

J'imagine que ça vient de l͠ :
<https://en.wikipedia.org/wiki/Data_structure_alignment>, notamment
<https://en.wikipedia.org/wiki/Data_structure_alignment#Typical_alignment_of_C_structs_on_x86>.
--
Benoit Izac
Avatar
Alain Ketterlin
Benoit Izac writes:
Le 04/02/2022 Í  16:29, "" a écrit
dans le message
 :
python -c 'import struct; print(struct.calcsize("4sIQ5I2Q"),
4+4+8+(5*4)+(2*8))'
56 52
une explication ?

J'imagine que ça vient de l͠ :
<https://en.wikipedia.org/wiki/Data_structure_alignment>, notamment
<https://en.wikipedia.org/wiki/Data_structure_alignment#Typical_alignment_of_C_structs_on_x86>.

C'est ça : l'alignement des deux derniers Q est 8 octets, mais la taile
de ce qui précède est congru Í  4 modulo 8. En clair pour la structure
entière ([x,y[ est l'intervalle x inclus y exclu), on commence en
position 0 :
00: 4s (4*1 octet, alignement 1 = ok) -> [0:4[
04: I (1*4 octets, alignement 4 = ok) -> [4:8[
08: Q (1*8 octets, alignement 8 = ok) -> [8:16[
16: 5I (5*4 octets, alignement 4 = ok) -> [16:36[
36: 2Q (2*8 octets, alignement 8 = problème, 36 est pas multiple de 8)
=> padding de 4 octets pour aligner -> [36:40[
=> puis 2Q -> [40:56[
La contrainte d'alignement dépend de l'architecture (et de choix du
compilateur). Un Q (unsigned long long en C) doit en général ête aligné
sur 8 octets (c'est le cas ici). Donc oui, il y a 4 octets dans la
structure qui ne servent Í  rien (entre 36 et 40 si je me suis pas gouré
dans les calculs). C'est d'ailleurs pour cela qu'on ne peut pas tester
l'égalité de structures octet par octet en C (le padding peut contenir
n'importe quoi).
Pour la même raison, tu trouveras (sÍ»rement) que "sQ" a une taille de
16, de même que "IQ", de même que "QI" Dans ce dernier exemple, le
padding est Í  la fin, mais il doit être lÍ  pour le cas o͹ tu veux faire
un tableau de telles structures (le deuxième élément du tableau doit
être aligné sur un multiple de 8).
Certaines architectures acceptent des données non alignées, par exemple
des "long long" de 8 octets alignés sur 4 octets, mais en général il
faut le demander explicitement, par exemple avec l'attribut "packed" en
C avec gcc et d'autres. C'est non portable. Et même si l'architecture le
supporte, cela peut être plus lent, parce qu'une donnée peut se trouver
Í  cheval sur deux lignes de cache.
-- Alain.
Avatar
pata...
bonjour,
merci pour vos explications.
cela est effectivement précisé dans la page de documentation Python (https://docs.python.org/3/library/struct.html).
l'utilisation de '=4sIQ5I2Q' (ajout du caractère spécial '=') retourne maintenant 52, ce que j'attendais.
cordialement, lacsaP.