Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
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 ?
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>.
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 ?
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.
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.
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.
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.
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.
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.