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
\**************************************************/

8 réponses

1 2 3
Avatar
Patrick 'Zener' Brunet
Bonsoir.

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

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

[...] quoting problem

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


Ma démarche étant de créer des types de base réutilisables, le minimum pour
ça est 1 octet.
Sinon il faut faire un bitfield global avec tous les membres de la
structure, comme dans ton exemple ci-dessous.

Disons que le type de 1 octet est un bon compromis pour moi: généralement
dans une classe genre noeud d'arbre, valeur temporelle, ou autre élément de
base d'une donnée complexe, on peut s'attendre à trouver de 1 à 3 booléens
et de 1 à 2 enums, plus quelques entiers.
Donc avec des types de 1 octet quand c'est possible, en les ordonnant bien,
on peut gagner dans les 16 octets sur cet exemple.

[...] exemple de "fagots"

Donc là j'avais même envisagé de regrouper plusieurs booléens sur un seul
octet, mais c'est sémantiquement horrible si on veut en faire un type
réutilisable, c'était le sens de la démo.

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.


Tiens, je ne savais pas que la syntaxe bitwidth (: n;) pouvait s'appliquer à
des types non-entiers...

Mais ça m'embête un peu de faire ça avec une class, et donc par ailleurs
exit les types génériques.
Je le ferai avec une structure si c'est vraiment indispensable, mais le gain
décrit ci-dessus me paraît convenable.


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.


Certes. Ca plaide aussi contre le bitfield global.

En fait tel que je le vois, il y aura en général une phase d'accès à la
bonne data dans un arbre très vaste, puis une phase de traitement de cette
data.
C'est la première phase qui nécessite des accès répétés et rapides dans un
volume important de données. Or elle va se baser sur des pointeurs et des
entiers "normaux" qui seront généralement en début de structure, pour
raisons d'alignement. Ca tombe bien.
Et donc en les réduisant (en nombre) au strict nécessaire, et en tassant le
reste, ça reste compatible avec la contrainte de volume.
Ensuite la seconde phase pourra être un peu plus lente, mais se répètera
beaucoup moins.
Donc globalement ça me paraît un bon compromis.

[...]

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.


Certes.
Mais ça peut être évité s'il n'y a pas d'échange de données entre
l'extérieur et l'intérieur d'un système, du moins dans la partie "moteur"
qui est le domaine de ces classes (donc ça relève de l'interface
spécifique).
Donc en interne, la seule singularité énorme et "buggante" de EBCDIC, c'est
qu'il y a des trous entre les plages de lettres, et que les chiffres
viennent après. Mais si le code ne fait pas de suppositions contradictoires,
se basant sur les isdigit(), isalpha() et autres, il peut rester portable.

[...]

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


C'est bien ça. Si je veux une union qui mappe deux 16bits sur un 32bits,
non-signés, je préfère le faire avec des U16 et un U32 que me demander si
tous les compilos seront d'accord sur "unsigned short" et "unsigned long".
Et on ne voit pas encore couramment les "long long"...
De même, si je dois stocker un nombre dont la dynamique dépasse 2^16, je
prends un U32 plutôt qu'un long, parce que si pour un système U32 n'est pas
possible, il ne se définira pas et le code ne pourra pas compiler.
Et en plus c'est visuellement plus clair, selon moi. Je me fais un peu
plaisir, certes...

[...]

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.


Un bonus bidon offert par certains compilos alors ? :-/
En tout cas il y a beaucoup de gens qui semblent se poser la question,
besoin ou pas... J'ai même vu un article sur WikiPedia, mais je ne le
retrouve plus.

Bon, pour ceux que ça pourrait dépanner, je vous offre ci-dessous les deux
petites classes que je me suis faites pour traiter le problème. J'ai fait
des essais et j'arrive à ce que je voulais: avec un char comme donnée, elles
tiennent sur 1 octet, même groupées en tableaux.
Ceci en utilisant le pragma de Pack de mon compilo, ce que je fais de
manière portable grâce à l'astuce ci-dessous aussi.

=============================
#define EZ_ALIGN_UNIT 1 /* Packed class */
#include <EzLocalPragma.h>

template< class T, class E>
class CSizedEnum
{
private:
T xValue;
public:
inline
CSizedEnum( void)
{
xValue = 0; /* Generally invalid until assigned */
};
inline
CSizedEnum( E const & rkeSource)
{
xValue = (T) (int) rkeSource;
};
public:
inline
CSizedEnum< T, E> const &
operator = ( E const & rkeSource)
{
xValue = (T) (int) rkeSource;
return( *this);
};
inline
operator E ( void) const
{
return( (E) (int) xValue);
};
};

template< class B>
class CSmallBool
{
private:
char zcValue;
public:
inline
CSmallBool( void)
{
zcValue = 0;
};
inline
CSmallBool( B bSource)
{
zcValue = (int) bSource;
};
public:
inline
CSmallBool< B> const &
operator = ( B bSource)
{
zcValue = (int) bSource;
return( *this);
};
inline
operator B ( void) const
{
return( zcValue != 0);
};
};

#define EZ_ALIGN_UNIT 0 /* Default back */
#include <EzLocalPragma.h>

===================================
Extrait de EzLocalPragma.h pour le principe:

#if defined( EZKNH_IS_MSVC_WIN32) /* Adapters for the Microsoft compiler
*/

#ifdef EZ_ALIGN_UNIT
/* Pragma changing the alignment boundary for structures and classes:
*
* the standard use should be with value 1 for packing, 0 to default
back. */
# if EZ_ALIGN_UNIT != 0
# pragma pack( EZ_ALIGN_UNIT) /* In bytes */
# else
# pragma pack() /* Restore compiler default */
# endif
# undef EZ_ALIGN_UNIT
#endif

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





Avatar
Patrick 'Zener' Brunet
Bonsoir.

"Michael DOUBEZ" a écrit dans le message news:
4670eaa0$0$2771$
"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 ç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.



Sisi, j'ai trouvé comment faire dès lors que le concept existe. Et s'il
n'existe pas, sans handicaper les autres systèmes.

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; file://! type de foo
u32 fonction:10; file://! fonction expected
u32 nbparam:4; file://! number of parameter
u32 bIsNegative:1; file://! negative ?
file://etc...
};



Pour info, je viens de décrire pourquoi je suis réticient pour le bitfield
global, et comment je gère l'alignement, dans ma réponse à James.

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





Avatar
James Kanze
Serge Paccalin wrote:
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 encoda ge :-@


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




Avatar
James Kanze
On Jun 14, 10:30 am, Serge Paccalin
wrote:
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 encoda ge :-@


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.


Est-ce Google qui le fait ? Parce que j'avais l'impression que
ça ne touche pas les posting que je fais de chez moi, également
à travers Google.

_/ _ _`_`_`_) 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).


C'est périmer, je crois. Il l'ont réparer, et le bouton
« Répondre » a l'air de fonctionner correctement maintenant.

--
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
James Kanze
On Jun 14, 10:16 pm, "Patrick 'Zener' Brunet"
wrote:

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

On Jun 13, 9:54 pm, "Patrick 'Zener' Brunet"

wrote:
[...] quoting problem
"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 ?


Ma démarche étant de créer des types de base réutilisables, le
minimum pour ça est 1 octet. Sinon il faut faire un bitfield
global avec tous les membres de la structure, comme dans ton
exemple ci-dessous.

Disons que le type de 1 octet est un bon compromis pour moi: générale ment
dans une classe genre noeud d'arbre, valeur temporelle, ou autre élém ent de
base d'une donnée complexe, on peut s'attendre à trouver de 1 à 3 b ooléens
et de 1 à 2 enums, plus quelques entiers.
Donc avec des types de 1 octet quand c'est possible, en les ordonnant bie n,
on peut gagner dans les 16 octets sur cet exemple.


Sans coût supplémentaire en temps, sur beaucoup de machines.

[...] exemple de "fagots"

Donc là j'avais même envisagé de regrouper plusieurs booléens sur un seul
octet, mais c'est sémantiquement horrible si on veut en faire un type
réutilisable, c'était le sens de la démo.


Le type réutilisable, c'est « bool »:-). Je ne vois pas de
problème per se dans l'utilisation des champs de bits dans les
structures, quand il faut gagner de la place. En revanche, il a
un coût important en temps d'exécution, et dans le cas des enum,
il y a aussi un coût en termes de maintainabilité : si
l'ajonction des valeurs dans l'enum en augmente la taille
minimum, il ne faut pas oublier de modifier la taille de tous
les champs de bits.

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.


Tiens, je ne savais pas que la syntaxe bitwidth (: n;) pouvait s'applique r à
des types non-entiers...


Il ne s'applique qu'aux types entiers et aux enum. Mais selon la
norme, bool est un type entier.

Mais ça m'embête un peu de faire ça avec une class, et donc par ail leurs
exit les types génériques.
Je le ferai avec une structure si c'est vraiment indispensable, mais le g ain
décrit ci-dessus me paraît convenable.

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.


Certes. Ca plaide aussi contre le bitfield global.


Sauf si le nombre d'éléments est énorme. C'est l'équilibre
classique entre l'utilisation de la mémoire et la vitesse
d'exécution.

Note bien que plus les données sont petites, plus la localité
est bonne. Et la localité peut jouer un rôle important dans les
performances sur une machine moderne.

Mais ce sont de genres de considérations que je ne prendrais en
compte que si l'application est réelement trop lente, et qu'il
faut l'optimiser.

[...]
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.


Certes.
Mais ça peut être évité s'il n'y a pas d'échange de données e ntre
l'extérieur et l'intérieur d'un système, du moins dans la partie "m oteur"
qui est le domaine de ces classes (donc ça relève de l'interface
spécifique).
Donc en interne, la seule singularité énorme et "buggante" de EBCDIC, c'est
qu'il y a des trous entre les plages de lettres, et que les chiffres
viennent après. Mais si le code ne fait pas de suppositions contradicto ires,
se basant sur les isdigit(), isalpha() et autres, il peut rester portable.


Tout à fait. C'est simplement que tu avais listé ASCII parmi des
choses « courantes ». Si tu programmes « correctement »,
c'est rare que l'encodage pose un problème. (C'est rare aussi
que le fait qu'un int soit 36 bits pose un problème non plus.)

[...]
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.


Un bonus bidon offert par certains compilos alors ? :-/


Je ne sais pas. Je ne l'ai jamais vu.

En tout cas il y a beaucoup de gens qui semblent se poser la question,
besoin ou pas... J'ai même vu un article sur WikiPedia, mais je ne le
retrouve plus.


Le WikiPedia évolve très vite. Il y apparaît toute sorte de
bêtises, qu'on remplace rapidement par d'autres bêtises quand on
se rend compte de la bêtise. En somme, c'est amusant pour
beaucoup de choses, mais je ne lui ferais pas de confiance si la
question a de l'importance.

Bon, pour ceux que ça pourrait dépanner, je vous offre ci-dessous les deux
petites classes que je me suis faites pour traiter le problème. J'ai fa it
des essais et j'arrive à ce que je voulais: avec un char comme donnée , elles
tiennent sur 1 octet, même groupées en tableaux.
Ceci en utilisant le pragma de Pack de mon compilo, ce que je fais de
manière portable grâce à l'astuce ci-dessous aussi.


Just une petite remarque...

======================== ======

#define EZ_ALIGN_UNIT 1 /* Packed class */
#include <EzLocalPragma.h>

template< class T, class E>


Je suppose que T serait toujours un type entier, et E un enum.
Donc...

class CSizedEnum
{
private:
T xValue;
public:
inline
CSizedEnum( void)
{
xValue = 0; /* Generally invalid until assigned */
};
inline
CSizedEnum( E const & rkeSource)


Ne serait-il pas préferable (ou au moins plus habituel) de
passer le paramètre par valeur ?

--
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
Stan
"Patrick 'Zener' Brunet" a écrit dans
le message de news:f4s7jo$eph$

Donc là j'avais même envisagé de regrouper plusieurs booléens sur un seul
octet, mais c'est sémantiquement horrible si on veut en faire un type
réutilisable, c'était le sens de la démo.



Ca me rappelle certains compilateurs ( pour microcontrolleurs )
où l'on peut effectivement adresser chaque bit ( bit-addressable objects )
d'un octet de la façon suivante :

char bdata flags[8]; /* bdata est un mot clé du compilo pour indiquer une
variable adressable bit à bit */

flags[2] = 1; /* met à 1 le 3 ème bit de la variable */


Faut dire que dans l'embarqué, fût un temps, on y allait
à l'économie;
maintenant avec la puissance sans cesse croissante...
--
-Stan

Avatar
Patrick 'Zener' Brunet
Bonsoir.

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

On Jun 14, 10:16 pm, "Patrick 'Zener' Brunet"
wrote:

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

On Jun 13, 9:54 pm, "Patrick 'Zener' Brunet"

wrote:
[...] quoting problem
"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$
[...]






Bon, pour ceux que ça pourrait dépanner, je vous offre ci-dessous les
deux


petites classes que je me suis faites pour traiter le problème. J'ai
fait


des essais et j'arrive à ce que je voulais: avec un char comme donnée,
elles


tiennent sur 1 octet, même groupées en tableaux.
Ceci en utilisant le pragma de Pack de mon compilo, ce que je fais de
manière portable grâce à l'astuce ci-dessous aussi.


Just une petite remarque...

=============================
#define EZ_ALIGN_UNIT 1 /* Packed class */
#include <EzLocalPragma.h>

template< class T, class E>

Je suppose que T serait toujours un type entier, et E un enum.
Donc...

class CSizedEnum
{
private:
T xValue;
public:
inline
CSizedEnum( void)
{
xValue = 0; /* Generally invalid until assigned */
};
inline
CSizedEnum( E const & rkeSource)


Ne serait-il pas préferable (ou au moins plus habituel) de
passer le paramètre par valeur ?


Oui bien sûr ! Je l'ai vu en relisant ce matin...
Je les ai pondues hier soir par clônage d'un operator= existant, et pressé
de vérifier pour la taille, j'ai fait un peu trop vite...
Pour un type atomique, sauf taille particulière (double, long double ?), le
passage par valeur est bien plus naturel.

Donc la nouvelle forme est:

CSizedEnum( E eSource)

idem pour operator = ( E eSource)


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





Avatar
Serge Paccalin
Le vendredi 15 juin 2007 à 08:36:23, James Kanze a écrit dans
fr.comp.lang.c++ :

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


Est-ce Google qui le fait ? Parce que j'avais l'impression que
ça ne touche pas les posting que je fais de chez moi, également
à travers Google.


Voilà les en-têtes de deux de tes messages récents :

Message-ID:
NNTP-Posting-Host: 86.70.189.165
Mime-Version: 1.0
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

et :

Message-ID:
NNTP-Posting-Host: 62.160.54.162
Mime-Version: 1.0
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

Je ne sais pas si l'un des deux sort de chez toi.

_/ _ _`_`_`_) 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).


C'est périmer, je crois. Il l'ont réparer, et le bouton
« Répondre » a l'air de fonctionner correctement maintenant.


Ah oui, ils ont encore tout chamboulé. Je reviens à mon ancienne
citation, alors.

--
___________
_/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net
_L_) Il faut donc que les hommes commencent
-'(__) par n'être pas fanatiques pour mériter
_/___(_) la tolérance. -- Voltaire, 1763


1 2 3