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

[C/C++] Support des types enum compacts (et de bool)

28 réponses
Avatar
Patrick 'Zener' Brunet
Bonsoir.

J'ai des classes qui se veulent "system independent", et que je dois rendre
très compactes.
Donc après les entiers bien calibrés, je me penche sur les formes compactes
du type enum, et aussi sur le booleen monobyte.

Donc short enum, char enum et bool.

Très difficile de trouver un bilan de leur support par les compilateurs
"assez" récents.

Je souhaite au strict minimum la portabilité Windows / Linux.
Dans la logique d'une librairie, je tiens aussi à ne pas fermer la porte aux
outils du fournisseur du système.

Donc après premier essai, MSVC v6.0 supporte bien bool, mais pas les enums
compacts :-(

**Auriez-vous des liens sur un état des lieux des divers compilos en service
?

Merci.

--
Cordialement.
--
/**************************************************\
* Patrick BRUNET
* E-mail: lien sur http://zener131.free.fr/ContactMe
\**************************************************/

10 réponses

1 2 3
Avatar
Michael DOUBEZ
In article ,
James Kanze wrote:

Le fichier <stdint.h> ne me semble pas si répandu que ça ; je
l'ai sous Linux, mais pas sous Solaris ni sous Windows.


Tu es un peu traditionnel et en retard. Ca m'etonnerait beaucoup
que les versions *recentes* des environnements de travail Windows
et Solaris n'aient pas stdint.h.


En fait, stdint n'est pas présent sous windows:
http://en.wikipedia.org/wiki/Stdint.h
<quote>
As stdint.h is currently NOT shipped with visual studio c++ products and
older c++ compilers, you may want to use some external one.

* pstdint.h - A cross-platform, free implementation from Paul
Hsieh. (Compilers tested (all with 0 warnings at their highest
respective settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits
and 32bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual
Studio.net (VC7), Intel C++ 4.0, GNU gcc v3.3.3)
* stdint.h - This stdint.h may be used with Microsoft compilers
only. But it fully C99 compliant and may be used with similar
inttypes.h. Tested with Microsoft Visual Studio .NET 2003 and Microsoft
Visual Studio .NET 2005.
</quote>

Sous solaris, il faut utiliser <inttypes.h> à la place.


Les choses evoluent vite. Il y a trois ans, c'etait courant de ne
pas avoir stdint.h. Aujourd'hui, ca denote de serieuses lacunes
de mise-a-jour...


L'intérèt de stdint est quand même marginal. J'utilise des uint8 ...
internes depuis longtemps. Le seul intérêt de l'intégrer dans le
standard est de ne pas re-inventer la roue.

Michael


Avatar
espie
In article <466fda79$0$14118$,
Michael DOUBEZ wrote:
In article ,
James Kanze wrote:

Le fichier <stdint.h> ne me semble pas si répandu que ça ; je
l'ai sous Linux, mais pas sous Solaris ni sous Windows.


Tu es un peu traditionnel et en retard. Ca m'etonnerait beaucoup
que les versions *recentes* des environnements de travail Windows
et Solaris n'aient pas stdint.h.


En fait, stdint n'est pas présent sous windows:
http://en.wikipedia.org/wiki/Stdint.h
<quote>
As stdint.h is currently NOT shipped with visual studio c++ products and
older c++ compilers, you may want to use some external one.

* pstdint.h - A cross-platform, free implementation from Paul
Hsieh. (Compilers tested (all with 0 warnings at their highest
respective settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits
and 32bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual
Studio.net (VC7), Intel C++ 4.0, GNU gcc v3.3.3)
* stdint.h - This stdint.h may be used with Microsoft compilers
only. But it fully C99 compliant and may be used with similar
inttypes.h. Tested with Microsoft Visual Studio .NET 2003 and Microsoft
Visual Studio .NET 2005.
</quote>


Beurk, au secours, tout ca.

Sous solaris, il faut utiliser <inttypes.h> à la place.


inttypes est complementaire de stdint.h...


Les choses evoluent vite. Il y a trois ans, c'etait courant de ne
pas avoir stdint.h. Aujourd'hui, ca denote de serieuses lacunes
de mise-a-jour...


L'intérèt de stdint est quand même marginal. J'utilise des uint8 ...
internes depuis longtemps. Le seul intérêt de l'intégrer dans le
standard est de ne pas re-inventer la roue.


A la reflexion, ca ne me surprend pas... le principal interet de stdint.h,
c'est la portabilite. Et on sait bien que windows n'en a rien a battre
de la portabilite....



Avatar
Michael DOUBEZ
In article <466fda79$0$14118$,
Michael DOUBEZ wrote:
In article ,
James Kanze wrote:

Le fichier <stdint.h> ne me semble pas si répandu que ça ; je
l'ai sous Linux, mais pas sous Solaris ni sous Windows.
Tu es un peu traditionnel et en retard. Ca m'etonnerait beaucoup

que les versions *recentes* des environnements de travail Windows
et Solaris n'aient pas stdint.h.
En fait, stdint n'est pas présent sous windows:

http://en.wikipedia.org/wiki/Stdint.h [snip]
Beurk, au secours, tout ca.


Sous solaris, il faut utiliser <inttypes.h> à la place.


inttypes est complementaire de stdint.h...

Les choses evoluent vite. Il y a trois ans, c'etait courant de ne
pas avoir stdint.h. Aujourd'hui, ca denote de serieuses lacunes
de mise-a-jour...
L'intérèt de stdint est quand même marginal. J'utilise des uint8 ...

internes depuis longtemps. Le seul intérêt de l'intégrer dans le
standard est de ne pas re-inventer la roue.


A la reflexion, ca ne me surprend pas... le principal interet de stdint.h,
c'est la portabilite. Et on sait bien que windows n'en a rien a battre
de la portabilite....



C'est surtout que windows a sont propre système de nommage avec lequel
uint8_t n'est pas vraiment compatible. En plus, il est rare sur PC
d'avoir besoin de savoir si un int fait 28,32 ou 64 bits sauf pour les
formats binaires de données.

Je travaille dans l'embarqué et en fonction des cultures les groupes de
travail utilisent u8,s8,u16,s16,u32,s32 ou uint8,sint8... ou uint8_t...
ou t_uint8 mais, paradoxalement, aucun n'utilise directement stdint.h :)
Et ils n'ont pas besoin de portabilité; c'est pour avoir un code clair
et qu'il y ait moins de problème le jour ou la plateforme change.

le header ressemble à:

typedef signed char sint8
#if ( sizeof(sint8) != 8 )
#error "Wrong size: sint8 - shoulb be 8"
#endif // ( sizeof(sint8) != 8 )
...


Michael




Avatar
espie
In article <466ffde8$0$13125$,
Michael DOUBEZ wrote:
le header ressemble à:

typedef signed char sint8
#if ( sizeof(sint8) != 8 )
#error "Wrong size: sint8 - shoulb be 8"
#endif // ( sizeof(sint8) != 8 )
...


Tiens, et la verif que CHAR_BIT est bien egale a 8, elle est ou ?
Pas tres portable tout ca.

Avatar
espie
In article <466ffde8$0$13125$,
Michael DOUBEZ wrote:

A la reflexion, ca ne me surprend pas... le principal interet de stdint.h,
c'est la portabilite. Et on sait bien que windows n'en a rien a battre
de la portabilite....




C'est surtout que windows a sont propre système de nommage avec lequel
uint8_t n'est pas vraiment compatible. En plus, il est rare sur PC
d'avoir besoin de savoir si un int fait 28,32 ou 64 bits sauf pour les
formats binaires de données.


Rappelons que uint8_t n'est pas garanti par la norme. uint_least8_t par
contre, oui.


Il est au contraire extremement frequent d'avoir des tailles minimales
a respecter quand on veut faire du code un minimum portable...


Avatar
James Kanze
On Jun 13, 11:53 am, (Marc Espie) wrote:
In article ,
James Kanze wrote:

Le fichier <stdint.h> ne me semble pas si répandu que ça ; je
l'ai sous Linux, mais pas sous Solaris ni sous Windows.


Tu es un peu traditionnel et en retard. Ca m'etonnerait beaucoup
que les versions *recentes* des environnements de travail Windows
et Solaris n'aient pas stdint.h.


Solaris 2.8 avec Sun CC 5.8. Pas les dernières versions, mais
pas vraiment si vieilles. Et le compilateur VC++, c'est la
version 2005. La dernière, je crois.

Et oui, ça m'a étonné aussi. J'étais sûr qu'il y était ;
heureusement, j'ai vérifié avant de poster.

Les choses evoluent vite. Il y a trois ans, c'etait courant de ne
pas avoir stdint.h. Aujourd'hui, ca denote de serieuses lacunes
de mise-a-jour...


Dans le cas de Solaris, c'est fort possible que je n'ai pas les
derniers patchs (et 2.8 n'est pas d'hier). Ma version de VC++,
en revanche, est on ne peut plus récente.

--
James Kanze (Gabi Software) email:
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
Patrick 'Zener' Brunet
Bonsoir.

Tout quoté à la main, ce *$#&! de OE ne reconnaît pas ton encodage :-@

"James Kanze" a écrit dans le message news:

On Jun 12, 7:48 pm, "Patrick 'Zener' Brunet"
wrote:
"Patrick 'Zener' Brunet"
a écrit dans le
messagenews:
*********_i?a63jfAD$

J'ai des classes qui se veulent "system independent",
et que je dois rendre très compactes.



Dans quel but ? Si tu as d'énormes tableaux des telles classes,
tu pourrais considérer des bit-fields ; ils ont été conçus
précisement pour ça.


J'avais pensé à utiliser des bitfields de 8bits comme "fagots de 8
booléens". Le problème c'est qu'il faut faire du typedef spécifique dans
chaque cas d'utilisation, il n'est pas possible de créer un tel type "fagot"
réutilisable, du moins qui ne soit pas très casse-gueule à l'utilisation.
Simplement parce qu'on ne peut nommer ainsi que le fagot, pas chacun des
"booléens":

typedef struct
{
int b1 : 1;
...
int b8 : 1;
} OctoBool;

Et ensuite pour l'utiliser:

OctoBool myOB;

myOB.b1 = true;
myOB.b2 = false;
...
myOB.b6 = (x <= 0);
...
if( myOB.b6)
{
}
...

A moins bien sur de faire aussi côté utilisation:

...
#define bIsNegative myOB.b6
...

Beuââârk, pas vrai ?
J'essaie de faire dans l'optimisé mais aussi très lisible.


Par "system independent", j'entends qu'elles sont compilables
(je n'attends évidemment aucune compatibilité binaire) sans
modification sur tout couple système + compilo "raisonnable",


« Raisonable » dépend du contexte où on se place, je crois.
Disons plutôt que tu n'as pas besoin d'une portabilité vers une
architecture « exotique » (parce que ce sont les différences
dans l'architecture qui conditionnent souvent les variations
dans les compilateurs).


Tout à fait. Je vise des domaines d'application que j'ai déjà bien vécus, et
qui couvrent le process industriel (PC et racks), la documentique, les
outils de développement orientés R&D (donc en général PC et autres micros),
etc.
Cela dit, en ce moment côté job je fais de l'IBM TPF, et même là ce serait
globalement appliquable :o)

c'est à dire:
- autorisant des entiers signés ou pas de 8, 16 et 32 bits
(à un nommage près),
- possédant des caractères de 8 bits et le code ASCII,
- et des pointeurs, sans besoin de compatibilité avec les
entiers, mais admettant 0 comme valeur invalide,
- et connaissant le typedef et les modifiers const, mutable
et volatile.


Ce sont des choses plus ou moins universel. Pour les deux
premiers, évidemment, le compilateur va s'aligner sur
l'architecture et le système ; on ne peut pas s'attendre à des
entiers à 32 bits si le hardware est à 36 bits, et les gros IBM
utilisent toujours de l'EBCDIC en natif (mais au moins à une
époque, le run-time du compilateur traduisait en ASCII pour
les fichiers texte, de façon à ce qu'interne, un programme en
C travaillait en ASCII).

La seule exception à ma connaissance est « volatile » ; ce
mot-clé n'a pas vraiment une sémantique normalisée, et sur les
compilateurs que je connais (Sun CC, g++ et VC++), ne fait
rien d'utile ou d'intéressant ; on pourrait prèsque le considérer
comme un no-op.


En fait, depuis plus de 10 ans, je m'appuie sur une typologie perso qui se
définit ad-hoc sur le couple système-compilo, moyennant la rédaction d'une
sorte de header "formulaire". Ca me met à l'abri des histoires de __int8 ou
int8_t et autres headers standards qui ne le sont pas vraiment.
Pour volatile par exemple, si nécessaire je peux le fournir comme une macro
no-op à ce niveau.
Tout mon code est bâti là-dessus, il est capable de gérer certains manques,
et par ailleurs très modulaire. La seule contrainte est que ce qui n'est
techniquement pas possible sur un système n'a aucune raison d'y être
compilé.

Alors bien sûr un système qui ne fournit pas d'entiers 32 bits semble
sémantiquement assez insuffisant selon cette approche.



Ces classes ne font aucune autre supposition sur le système,
et n'utilisent directement aucune primitive qui le fasse, même
de la stdio. Toutes les primitives de ce type sont reportées
dans des modules de portage totalement substituables.

Mais bon, c'est pas le but de la discussion. Ce qui
m'intéresse, c'est la disponibilité de certains types récents
(introduits par C99, et parfois anticipés par certains
compilos).


Le fichier <stdint.h> ne me semble pas si répandu que ça ; je
l'ai sous Linux, mais pas sous Solaris ni sous Windows.


Donc j'ai mes "types certifiés" à la place, on n'est jamais si bien servi...

Donc après les entiers bien calibrés, je me penche sur les
formes compactes du type enum, et aussi sur le booleen
monobyte.

Donc short enum, char enum et bool.


Sachant que théoriquement lorsqu'il est supporté, bool est
supposé tenir sur un octet.


Je ne sais pas d'où tu as ça. La norme ne dit rien sur la taille
d'un bool. Sur une architecture où les accès à un octet sont
aussi vite que ceux à un mot, je m'attendrais bien que la taille
de bool soit 1. Mais sur des architectures où un accès mot est
plus rapide qu'un accès octet, il y a un choix entre vitesse et
espace à faire, et ça ne m'étonnerait pas que beaucoup de
compilateurs choisissent la vitesse.


Oui.
Actuellement mon Bool se définit sur bool si ça m'arrange, mais je peux très
bien le définir sur char.


Et que par ailleurs pour enum, si le type par défaut est bien
supposé être compatible en taille avec un int, il admet des
modifieurs qui sont normalement char, short, long et long
long.


Comment ça ? La norme ne dit rien en ce qui concerne la taille
d'un enum, sauf qu'il soit assez grand pour contenir toutes les
valeurs, et qu'il ne soit pas plus grand qu'un int, sauf s'il le
faut.


Oui, je crois que j'ai fait une méprise entre C99 et C++ à ce niveau.

En cherchant sur Google, j'ai trouvé beaucoup de sites qui parlent des
formes modifiées d'enum, et c'est pour ça qu'au début je demandais des liens
vers une référence pour tenter de faire le point.

Entre temps, j'ai vérifié que mon compilo VC6, s'il connaît bool, ne connaît
pas short enum.

Alors je vais m'en tirer en utilisant une classe template en <T, E> pour
gérer un T interne avec une interface externe d'enum E.

Merci pour ton expertise.

--
Cordialement.
--
/**************************************************
* Patrick BRUNET
* E-mail: lien sur http://zener131.free.fr/ContactMe
**************************************************/



Avatar
James Kanze
On Jun 13, 9:54 pm, "Patrick 'Zener' Brunet"
wrote:

Tout quoté à la main, ce *$#&! de OE ne reconnaît pas ton encodage :-@


Je sais. Il y a quelque chose de particulier qui s'ajoute à mes
postings quand je poste du travail. Je suis en train d'en
chercher la cause, mais ce n'est pas facile ; le message est
traité par tellement d'intermédiaires avant qu'il soit injecté
dans le flux NNTP. (Autant que je sache, l'encodage final est
légal, et OE doit le reconnaître. Mais il n'est pas
« correct » non plus, en ce qu'il ne correspond pas à ce que
j'ai voulu ou que j'ai envoyé.)

"James Kanze" a écrit dans le message news:

On Jun 12, 7:48 pm, "Patrick 'Zener' Brunet"

wrote:
"Patrick 'Zener' Brunet"
a écrit dans le
messagenews:
*********_i?a63jfAD$
J'ai des classes qui se veulent "system independent",
et que je dois rendre très compactes.
Dans quel but ? Si tu as d'énormes tableaux des telles classes,


tu pourrais considérer des bit-fields ; ils ont été conçus
précisement pour ça.


J'avais pensé à utiliser des bitfields de 8bits comme "fagots de 8
booléens".


Pourquoi un bit-field de 8 bits si ce sont des booléens ?
Pourquoi pas directement 1 bit ?

Le problème c'est qu'il faut faire du typedef spécifique dans
chaque cas d'utilisation, il n'est pas possible de créer un
tel type "fagot" réutilisable, du moins qui ne soit pas très
casse-gueule à l'utilisation.


Il serait plus facile à en parler si on savait ce que tu
essayais à faire. Si tu as des tableaux de booléens, il y a des
classes dans la bibliothèque standard qui les font, packés un
bool par bit. L'accès n'est pas aussi rapide que si tu utilises
un bool[], mais la place occupée est bien moindre. Si en
revanche tu as des structures qui comportent beaucoup de bool et
de petits enum, les bit-field sont la solution quand il s'agit
de gagner de la place mémoire.

Simplement parce qu'on ne peut
nommer ainsi que le fagot, pas chacun des "booléens":

typedef struct
{
int b1 : 1;
...
int b8 : 1;

} OctoBool;

Et ensuite pour l'utiliser:

OctoBool myOB;

myOB.b1 = true;
myOB.b2 = false;
...
myOB.b6 = (x <= 0);
...
if( myOB.b6)
{}

...

A moins bien sur de faire aussi côté utilisation:

...
#define bIsNegative myOB.b6
...

Beuââârk, pas vrai ?


Je n'ai pas trop compris ce que tu essaies de faire. Si tu as
des noms du genre bIsNegative, et ton point du départ est
quelque chose du genre :

enum X { ... } ;
struct Toto
{
bool isNegative ;
X attributeX ;
// ...
} ;

Il suffit d'ajouter des spécifications de bit-field à chaque
champs :

struct Toto
{
bool isNegative : 1 ;
X attributeX : 3 ;
// ...
} ;

C'est tout ; le complateur s'occupe de toute la reste.

Maintenant, si tu as d'énormes tableaux des telles structures,
mais tu as aussi des bouts de code où tu en manipules que deux
ou trois, mais qu'il faut que ce soit vite, il se peut que tu
aies besoin de deux structures, un PackedToto et un Toto, parce
que l'accès à un bit-field est nettement moin rapide qu'à un
bool ou à un enum ordinaire. Et du coup, il te faudrait aussi
des fonctions de conversions.

J'essaie de faire dans l'optimisé mais aussi très lisible.

Par "system independent", j'entends qu'elles sont compilables
(je n'attends évidemment aucune compatibilité binaire) sans
modification sur tout couple système + compilo "raisonnable",


« Raisonable » dépend du contexte où on se place, je crois.
Disons plutôt que tu n'as pas besoin d'une portabilité vers une
architecture « exotique » (parce que ce sont les différences
dans l'architecture qui conditionnent souvent les variations
dans les compilateurs).


Tout à fait. Je vise des domaines d'application que j'ai déjà bien vécus, et
qui couvrent le process industriel (PC et racks), la documentique, les
outils de développement orientés R&D (donc en général PC et autre s micros),
etc.
Cela dit, en ce moment côté job je fais de l'IBM TPF, et même là ce serait
globalement appliquable :o)


Y compris l'ASCII ? La dernière fois que j'ai eu à faire avec
des gros IBM, c'était du CICS, et c'était EBCDIC. Et BCD ou IBM
flottant (et non IEEE) pour les nombres. À part les entiers, on
avait à traduire tout et à l'entrée et à la sortie.

c'est à dire:
- autorisant des entiers signés ou pas de 8, 16 et 32 bits
(à un nommage près),
- possédant des caractères de 8 bits et le code ASCII,
- et des pointeurs, sans besoin de compatibilité avec les
entiers, mais admettant 0 comme valeur invalide,
- et connaissant le typedef et les modifiers const, mutable
et volatile.
Ce sont des choses plus ou moins universel. Pour les deux

premiers, évidemment, le compilateur va s'aligner sur
l'architecture et le système ; on ne peut pas s'attendre à des
entiers à 32 bits si le hardware est à 36 bits, et les gros IBM
utilisent toujours de l'EBCDIC en natif (mais au moins à une
époque, le run-time du compilateur traduisait en ASCII pour
les fichiers texte, de façon à ce qu'interne, un programme en
C travaillait en ASCII).
La seule exception à ma connaissance est « volatile » ; ce
mot-clé n'a pas vraiment une sémantique normalisée, et sur les
compilateurs que je connais (Sun CC, g++ et VC++), ne fait
rien d'utile ou d'intéressant ; on pourrait prèsque le considérer
comme un no-op.


En fait, depuis plus de 10 ans, je m'appuie sur une typologie perso qui se
définit ad-hoc sur le couple système-compilo, moyennant la rédactio n d'une
sorte de header "formulaire". Ca me met à l'abri des histoires de __int 8 ou
int8_t et autres headers standards qui ne le sont pas vraiment.
Pour volatile par exemple, si nécessaire je peux le fournir comme une m acro
no-op à ce niveau.


Pas besoin, parce que c'est pratiquement un no-op sur les
compilateurs classique de toute façon.

Tout mon code est bâti là-dessus, il est capable de gérer certains manques,
et par ailleurs très modulaire. La seule contrainte est que ce qui n'est
techniquement pas possible sur un système n'a aucune raison d'y être
compilé.

Alors bien sûr un système qui ne fournit pas d'entiers 32 bits semble
sémantiquement assez insuffisant selon cette approche.


Pourquoi est-ce que tu as besoin d'une taille exacte ? En
général, une taille minimum me suffit ; qui peut le plus, peut
le moins. (Il y a quelques exceptions, et je suis partie du
principe d'un type d'exactement 8 bits et un d'exactement 32 ou
64 bits dans mes fonctions SHA et CRC. Mais partout ailleurs,
non.)

[...]
Et que par ailleurs pour enum, si le type par défaut est bien
supposé être compatible en taille avec un int, il admet des
modifieurs qui sont normalement char, short, long et long
long.
Comment ça ? La norme ne dit rien en ce qui concerne la taille

d'un enum, sauf qu'il soit assez grand pour contenir toutes les
valeurs, et qu'il ne soit pas plus grand qu'un int, sauf s'il le
faut.


Oui, je crois que j'ai fait une méprise entre C99 et C++ à ce niveau.


Il n'y a pas de différence en ce qui concerne la taille. Selon
C99 : « Each enumerated type shall be compatible with char, a
signed integer type, or an unsigned integer type. The choice of
type is implementation-defined, but shall be capable of
representing the values of all the members of the
enumeration. » C'est à peu près ce que dit la norme C++. Les
différences entre les deux sont d'une part que le C++ permet
aussi des constantes d'enum plus grandes qu'un int (ce qui
impose que certains enum soient plus grands qu'un int), que le
C++ définit des limites sur des valeurs permises lors des
conversions en type enum, et surtout, qu'en C++, le type de la
constante se transforme, et change d'int en enum à la fin de
l'enum, et qu'il n'y a pas de conversion implicite d'int vers
enum.

En cherchant sur Google, j'ai trouvé beaucoup de sites qui
parlent des formes modifiées d'enum, et c'est pour ça qu'au
début je demandais des liens vers une référence pour tenter de
faire le point.

Entre temps, j'ai vérifié que mon compilo VC6, s'il connaît
bool, ne connaît pas short enum.


Peut-être parce qu'il ne fait pas partie de C++, et n'en a
jamais fait partie, ni de C++ ni de C.

--
James Kanze (GABI Software, from CAI) email:
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
Michael DOUBEZ
Bonsoir.

Tout quoté à la main, ce *$#&! de OE ne reconnaît pas ton encodage :-@

"James Kanze" a écrit dans le message news:

On Jun 12, 7:48 pm, "Patrick 'Zener' Brunet"
wrote:
"Patrick 'Zener' Brunet"
a écrit dans le
messagenews:
*********_i?a63jfAD$

J'ai des classes qui se veulent "system independent",
et que je dois rendre très compactes.



Dans quel but ? Si tu as d'énormes tableaux des telles classes,
tu pourrais considérer des bit-fields ; ils ont été conçus
précisement pour ça.


J'avais pensé à utiliser des bitfields de 8bits comme "fagots de 8
booléens". Le problème c'est qu'il faut faire du typedef spécifique dans
chaque cas d'utilisation, il n'est pas possible de créer un tel type "fagot"
réutilisable, du moins qui ne soit pas très casse-gueule à l'utilisation.
Simplement parce qu'on ne peut nommer ainsi que le fagot, pas chacun des
"booléens":

typedef struct
{
int b1 : 1;
...
int b8 : 1;
} OctoBool;

Et ensuite pour l'utiliser:

OctoBool myOB;

myOB.b1 = true;
myOB.b2 = false;
...
myOB.b6 = (x <= 0);
...
if( myOB.b6)
{
}
...

A moins bien sur de faire aussi côté utilisation:

...
#define bIsNegative myOB.b6
...

Beuââârk, pas vrai ?
J'essaie de faire dans l'optimisé mais aussi très lisible.


Et ça ne résoud rien car les contraintes d'alignement font que
potentiellement sizeof(OctoBool)==sizeof(int) a moins d'utiliser un
pragma de type pack si celui ci est dispo mais c'est pas/peu portable.

Donc tes tableaux et structures d'OctoBool sont condamnés au gigantisme :)
A la place de ton octobool, tu peux regarder du coté des biset<> si tu
as des besoins évolués.

A ce que j'ai compris, ce que James Kanze te propose est de définir tes
structures directement avec des bit-fields pour les rendre compacte:
struct foo
{
s32 type:3; //! type de foo
u32 fonction:10; //! fonction expected
u32 nbparam:4; //! number of parameter
u32 bIsNegative:1; //! negative ?
//etc...
};

Sans passer par un header de standardisation.

Maintenant, le padding peut changer d'une architecture à l'autre en
théorie (je ne suis pas sûr de ça) mais la taille des champs est fixe et
compacte.

Michael




Avatar
Serge Paccalin
Le jeudi 14 juin 2007 à 09:05:13, James Kanze a écrit dans
fr.comp.lang.c++ :

Tout quoté à la main, ce *$#&! de OE ne reconnaît pas ton encodage :-@


Je sais. Il y a quelque chose de particulier qui s'ajoute à mes
postings quand je poste du travail. Je suis en train d'en
chercher la cause,


Google publie en Quoted-Printable ; c'est ça qu'OE refuse de citer.

--
___________
_/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net
_L_) Pour bien répondre avec Google, ne pas cliquer
-'(__) « Répondre », mais « Afficher les options »,
_/___(_) puis cliquer « Répondre » (parmi les options).


1 2 3