OVH Cloud OVH Cloud

PB débutant

19 réponses
Avatar
Olivier
Bonjour,

J'ai un petit probleme de comprehension de déclaration de variable dans un
programme en Visual C++.

DWORD dwNameLen : 6

que signifie ": 6" ????

Cordialement,

Olivier

10 réponses

1 2
Avatar
Fabien LE LEZ
On Tue, 15 Mar 2005 19:22:41 +0100, "Olivier" :

J'ai un petit probleme de comprehension de déclaration de variable dans un
programme en Visual C++.

DWORD dwNameLen : 6


Logiquement, il s'agit d'un membre d'une classe. Le ":6" indique que
le membre en question n'occupe que 6 bits.
Exemple :

struct Machin
{
unsigned long x: 7;
unsigned long y: 8;
unsigned long z: 17;
};

Un "Machin" fait 32 bits en tout, bien qu'il ait 3 éléments.

Note que tout ça est hautement non portable (et un peu passé de mode
il me semble). Par conséquent, mieux vaut savoir le lire mais ne
jamais avoir à l'écrire.


--
;-)

Avatar
kanze
Fabien LE LEZ wrote:
On Tue, 15 Mar 2005 19:22:41 +0100, "Olivier" :

J'ai un petit probleme de comprehension de déclaration de
variable dans un programme en Visual C++.

DWORD dwNameLen : 6


Logiquement, il s'agit d'un membre d'une classe. Le ":6"
indique que le membre en question n'occupe que 6 bits.
Exemple :

struct Machin
{
unsigned long x: 7;
unsigned long y: 8;
unsigned long z: 17;
};

Un "Machin" fait 32 bits en tout, bien qu'il ait 3 éléments.


La taille d'un "Machin" dépend toujours sur l'implémentation.
Disons qu'il ferait au moins 32 bits, et prèsque certainement
moins que s'il n'y avait pas des :x derrière.

Note que tout ça est hautement non portable (et un peu passé
de mode il me semble).


Qu'est-ce qui te fait dire ça ? Quand j'ai commencé le C, on les
évitait, en effet, parce que certains compilateurs en avaient
des problèmes. Mais c'était 1983, environ. Depuis, c'est à
espérer qu'ils ont résolu ces problèmes.

En revanche, c'est effectivement un peu tombé de mode, du fait
que c'est une optimization de l'espace, et les mémoires sont
devenues nettement plus grandes qu'avant. N'empèche que si
j'avais des millions d'enrégistrements, et que chaque
enrégistrement avait beaucoup de champs avec 2 ou 3 valeurs, je
m'en servirai, encore aujourd'hui.

--
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
Olivier
Merci pour vos réponses...
Donc si j'ai bien compris,

struct Machin
{
DWORD Truc : 6, Chose : 26;
};

Signifie que la structure Machin à une taille de DWORD, 4 octets, soit 32
bits et qu'elle est composée de Truc qui fait 6 bits et Chose qui en fait 26
!!??
Par contre une autre question, Truc = 6 premiers bits, 6 derniers ou au
hasard dans les 32 bits ?

Désolé, je débute...

Cordialement,

Olivier

a écrit dans le message de
news:
Fabien LE LEZ wrote:
On Tue, 15 Mar 2005 19:22:41 +0100, "Olivier" :

J'ai un petit probleme de comprehension de déclaration de
variable dans un programme en Visual C++.

DWORD dwNameLen : 6


Logiquement, il s'agit d'un membre d'une classe. Le ":6"
indique que le membre en question n'occupe que 6 bits.
Exemple :

struct Machin
{
unsigned long x: 7;
unsigned long y: 8;
unsigned long z: 17;
};

Un "Machin" fait 32 bits en tout, bien qu'il ait 3 éléments.


La taille d'un "Machin" dépend toujours sur l'implémentation.
Disons qu'il ferait au moins 32 bits, et prèsque certainement
moins que s'il n'y avait pas des :x derrière.

Note que tout ça est hautement non portable (et un peu passé
de mode il me semble).


Qu'est-ce qui te fait dire ça ? Quand j'ai commencé le C, on les
évitait, en effet, parce que certains compilateurs en avaient
des problèmes. Mais c'était 1983, environ. Depuis, c'est à
espérer qu'ils ont résolu ces problèmes.

En revanche, c'est effectivement un peu tombé de mode, du fait
que c'est une optimization de l'espace, et les mémoires sont
devenues nettement plus grandes qu'avant. N'empèche que si
j'avais des millions d'enrégistrements, et que chaque
enrégistrement avait beaucoup de champs avec 2 ou 3 valeurs, je
m'en servirai, encore aujourd'hui.

--
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
Michel Michaud
Dans le message 42388f8b$0$15287$,
Merci pour vos réponses...
Donc si j'ai bien compris,

struct Machin
{
DWORD Truc : 6, Chose : 26;
};

Signifie que la structure Machin à une taille de DWORD, 4 octets,
soit 32 bits et qu'elle est composée de Truc qui fait 6 bits et
Chose qui en fait 26 !!??


Non. Seulement que Truc aura au moins 6 bits utilisables et Chose
en aura au moins 24. Au total, tu ne peux pas compter sur la taille
sans te fier à la documentation de ton compilateur spécifique (et
souvent selon ses options).

Par contre une autre question, Truc = 6 premiers bits, 6 derniers
ou au hasard dans les 32 bits ?


Non défini par ISO C++. Voir la documentation de ton compilateur
si c'est important.

Désolé, je débute...


Alors ce n'est vraiment pas le genre de choses qui devrait t'être
utile dans tes programmes...

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/

Avatar
tibug

Dans le message 42388f8b$0$15287$,

Alors ce n'est vraiment pas le genre de choses qui devrait t'être
utile dans tes programmes...


beh je débute aussi et je me tracasse aussi quand je tombe sur un truc
que je ne comprend pas (à peu près tout ;-)

En particulier pour les types, ça peut dérouter un débutant d'apprendre
qu'un 'int' n'ait pas la même capacité sur telle ou telle machine, et de
devoir jeter un oeil à limits.h pour définir un uint32 portable :)

[soyez indulgent si vous voyez des immondités dans les commentaires
ci-dessous (i.e. pas sur la tête ;-)

struct Machin
{
Chose : 26; // tout ce qu'on veut, c'est que le type 'Chose' puisse
// *au moins* contenir 26 bits, on choisit pour 'Chose' le
}; // type plus petit (>= 26)


Définir ainsi explicitement la "pseudo" taille des membre en bits
peut être utile pour des opérations sur des champs de bits.

Ci-desous un exemple de ce type de structure (tiré de id3lib)
pour réaliser une "copie de buffer sur structure" à l'aide de
l'opérateur 'reinterpret_cast' :

[il s'agit de lire les 32 bits de l'entête d'une frame mp3 et de
renseigner les membres d'une structure suivant la valeur des bits lus :


-- /id3lib-stable/src/mp3_header.h ----

// on définit un type de de structure pour une entête mp3 de 32 bits :
// http://www.mp3-tech.org/programmer/frame_header.html

struct _mp3_header_internal {

// on définit les membres (dans l'ordre!), en utilisant des
// unsigned char parceque l'on a pas besoin plus de 8 bits :

//byte 1
unsigned char frame_sync_a : 8; /* all bits should be set */
//byte 2
unsigned char protection_bit : 1;
unsigned char layer : 2;
unsigned char id : 2;
unsigned char frame_sync_b : 3; /* all bits should be set */
//byte 3
unsigned char private_bit : 1;
unsigned char padding_bit : 1;
unsigned char frequency : 2;
unsigned char bitrate_index : 4;
//byte 4
unsigned char emphasis : 2;
unsigned char original : 1;
unsigned char copyright : 1;
unsigned char mode_ext : 2; /* only used in joint stereo */
unsigned char mode : 2;
};


-- /id3lib-stable/src/mp3_parse.cpp ---

_mp3_header_internal *_tmpheader; // une struct pour header

const size_t HEADERSIZE = 4; // 4 o = "pseudo" taille de la struct
char buf[HEADERSIZE+1]; // buffer pour l'entête lue dans mp3
//+1 to hold the char

...

reader.readChars(buf, HEADERSIZE); // remplit le buffer à partir
buf[HEADERSIZE]=''; // de 32 bits lu dans le fichier

...
// copie le buffer sur la structure en fixant la valeur
// des membre de _tmpheader à leurs homologues dans le buffer :

_tmpheader = reinterpret_cast<_mp3_header_internal *>(buf);
...


voilà, A+

tibug

Avatar
James Kanze
Michel Michaud wrote:
Dans le message 42388f8b$0$15287$,


Merci pour vos réponses...
Donc si j'ai bien compris,



struct Machin
{
DWORD Truc : 6, Chose : 26;
};



Signifie que la structure Machin à une taille de DWORD, 4
octets, soit 32 bits et qu'elle est composée de Truc qui fait
6 bits et Chose qui en fait 26 !!??



Non. Seulement que Truc aura au moins 6 bits utilisables et
Chose en aura au moins 24.


Non. Il est garanti que Truc a exactement 6 bits, et Chose 26.
Dans la mésure que les types sont signés, évidemment, c'est
difficile pour un programme conforme de le savoir, mais s'il
sont unsigned, si Truc vaut 63, ++ Truc vaut 0. Garanti par la
norme.

Il n'y aucune garantie en ce concerne la taille de
Machin, mais l'intention est clairement précisée que si la
taille d'un DWORD est 32 bits ou plus, que et Truc et Chose se
trouvent dans le même DWORD.

Au total, tu ne peux pas compter sur la taille sans te fier à
la documentation de ton compilateur spécifique (et souvent
selon ses options).


Par contre une autre question, Truc = 6 premiers bits, 6
derniers ou au hasard dans les 32 bits ?



Non défini par ISO C++. Voir la documentation de ton
compilateur si c'est important.


Si c'est important, les bit field ne sont probablement pas
l'outil qui convient. Ça peut varier d'un compilateur à l'autre,
même sur le même système.

Désolé, je débute...



Alors ce n'est vraiment pas le genre de choses qui devrait
t'être utile dans tes programmes...


Il n'a pas dit qu'il voulait s'en servir ; il a vu qu'il l'a vu,
et qu'il voulait comprendre ce qu'il a vu.

--
James Kanze home: www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34


Avatar
Michel Michaud
Dans le message 423c53f1$0$21961$,
Michel Michaud wrote:
Dans le message 42388f8b$0$15287$,

Merci pour vos réponses...
Donc si j'ai bien compris,

struct Machin
{
DWORD Truc : 6, Chose : 26;
};

Signifie que la structure Machin à une taille de DWORD, 4
octets, soit 32 bits et qu'elle est composée de Truc qui fait
6 bits et Chose qui en fait 26 !!??


Non. Seulement que Truc aura au moins 6 bits utilisables et
Chose en aura au moins 24.


Non. Il est garanti que Truc a exactement 6 bits, et Chose 26.


Je ne suis pas certain que c'est ce que dit la norme (je viens
de relire la norme C, ça ne me semble pas aussi clair). Je sais
évidemment que c'est l'intention.

Je comprends surtout que ma phrase ne semble pas dire exactement
à quoi je pensais (et qui reste peut-être faux...). Je voulais dire
que le compilateur allouera au moins 6 bits pour que Truc ait bien
ses 6 bits utilisables, etc.

Dans la mésure que les types sont signés, évidemment, c'est
difficile pour un programme conforme de le savoir, mais s'il
sont unsigned, si Truc vaut 63, ++ Truc vaut 0. Garanti par la
norme.


Oui, je suis parfaitement d'accord. Mais il me semble possible que
les 6 bits de Truc ne soit ni complètement à gauche ni complètement
à droite de l'espace alloué. C'est là que je ne suis pas capable de
confirmer en lisant la norme... Dans mon esprit, si j'ai besoin de
manipuler 6 bits dans quelque chose, je vais le faire avec des
décalages et des masques, car je suis sous l'impression que les
champs de bits ne me garantissent rien. Peut-être que je me trompe,
c'est une vieille idée que j'ai en tête (et comme je ne fais plus
beaucoup de manipulations de bits, elle ne m'a jamais vraiment
dérangée :-)

Il n'y aucune garantie en ce concerne la taille de
Machin, mais l'intention est clairement précisée que si la
taille d'un DWORD est 32 bits ou plus, que et Truc et Chose se
trouvent dans le même DWORD.


Oui, on est d'accord sur l'intention. Par contre, sur une machine
bizarre, je crois que le compilateur pourrait allouer beaucoup
plus, par exemple deux mots de 32 bits. Encore une fois, je ne suis
pas capable de confirmer/infirmer en lisant la norme.

[...]
Désolé, je débute...


Alors ce n'est vraiment pas le genre de choses qui devrait
t'être utile dans tes programmes...


Il n'a pas dit qu'il voulait s'en servir ; il a vu qu'il l'a vu,
et qu'il voulait comprendre ce qu'il a vu.


Je n'ai pas dit qu'il n'a pas à le savoir si ça l'intéresse.
D'ailleurs, tu remarqueras que je répondais à sa question ! Je lui
dis simplement que ce n'est pas très utile pour les programmes
faits par un débutant. C'est important de comprendre qu'il ne faut
pas paniquer si on trouve ça bien bizarre ou complexe, ou qu'on
n'en voit pas l'utilité :-)

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/



Avatar
Michel Michaud
Dans le message 423b79bf$0$25041$,
Alors ce n'est vraiment pas le genre de choses qui devrait t'être
utile dans tes programmes...


beh je débute aussi et je me tracasse aussi quand je tombe sur un
truc que je ne comprend pas (à peu près tout ;-)

En particulier pour les types, ça peut dérouter un débutant
d'apprendre qu'un 'int' n'ait pas la même capacité sur telle ou
telle machine, et de devoir jeter un oeil à limits.h pour définir
un uint32 portable :)


Je ne suis pas certain que c'est le genre de trucs qui devrait
préoccuper les débutants : le plus important est souvent de savoir
que int a au moins 16 bits et long au moins 32. Par ailleurs, il
est bon de savoir qu'on peut définir un type uint32 portable si
on en a vraiment besoin...

(Pour le reste, il faut simplement savoir que les champs de bits
peuvent probablement simplifier les programmes qui manipulent des
bits, au détriment de faire un programme vraiment portable.)

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/


Avatar
Fabien LE LEZ
On Sat, 19 Mar 2005 14:34:16 -0500, "Michel Michaud" :

car je suis sous l'impression que les
champs de bits ne me garantissent rien.


C'est bien ce qu'il m'avait semblé également : les champs de bits
peuvent servir à économiser la mémoire, mais en aucun cas à bricoler
des bits d'une variable.

Il n'y aucune garantie en ce concerne la taille de
Machin, mais l'intention est clairement précisée que si la
taille d'un DWORD est 32 bits ou plus, que et Truc et Chose se
trouvent dans le même DWORD.


Oui, on est d'accord sur l'intention. Par contre, sur une machine
bizarre, je crois que le compilateur pourrait allouer beaucoup
plus, par exemple deux mots de 32 bits.


Il me semble qu'un compilo pourrait décider (éventuellement via une
option de compilation) qu'en fait, allouer un DWORD par variable
permettrait au programme d'aller plus vite (en alig

struct Machin
{
DWORD Truc : 6, Chose : 26;
};




--
;-)


Avatar
Fabien LE LEZ
On Sat, 19 Mar 2005 14:34:16 -0500, "Michel Michaud" :

car je suis sous l'impression que les
champs de bits ne me garantissent rien.


C'est bien ce qu'il m'avait semblé également : les champs de bits
peuvent servir à économiser la mémoire, mais en aucun cas à bricoler
des bits d'une variable.

Il n'y aucune garantie en ce concerne la taille de
Machin, mais l'intention est clairement précisée que si la
taille d'un DWORD est 32 bits ou plus, que et Truc et Chose se
trouvent dans le même DWORD.


Oui, on est d'accord sur l'intention. Par contre, sur une machine
bizarre, je crois que le compilateur pourrait allouer beaucoup
plus, par exemple deux mots de 32 bits.


Il me semble qu'un compilo pourrait décider (éventuellement via une
option de compilation) qu'en fait, allouer un DWORD par variable
permettrait au programme d'aller plus vite (en alignant "Chose" sur un
DWORD). Mais je ne sais pas si un tel comportement serait conforme.


--
;-)


1 2