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

Output

25 réponses
Avatar
Guillaume GOURDIN
Bonjour à tous,

j'ai un problème, le code suivat :

uint8_t data1, data2;
cout << "0x" << hex << setw(4) << setfill('0') << data1 << "=";
cout << "0x" << hex << setw(2) << setfill('0') << data2 << endl;

me sort l'output suivant :

0x00aa=0x0

alors que je m'attendrais (et que je voudrais) quelque chose du genre:

0x00aa=0x00

Vous avez des idées?

10 réponses

1 2 3
Avatar
Sylvain
James Kanze wrote on 09/03/2008 12:04:
On 8 mar, 23:40, Sylvain wrote:
James Kanze wrote on 07/03/2008 22:01:
Le type influence bien comment on y accède.


c'est en substance tout à fait contradictoire avec tes
positions du fil précédent.


Explique, si te plais. Je ne vois pas comment le type ne
pourrait pas influencer comment on accède aux objets---quand
j'accède à travers un lvalue de type char, par exemple, je
n'accède qu'aux huit bits, tandis qu'avec int... Et je suis
certain de ne jamais avoir dit le contraire.


contradictoire avec:


"À la mise sous tension, la mémoire contient effectivement"
"n'importe quoi. (Aussi, la plupart des contrôleurs dont je me"
"suis servi dans le temps prévoyaient bien une commande pour"
"écrire des valeurs erronées. Pour des motifs de test, si rien"
"d'autre. Mais le problème réel, c'est que jusqu'à la première"
"écriture, le contenu n'est pas défini, et il y a des chances"
"qu'il soit invalid.)"

la "mise sous tension" ne préjuge pas du fait qu'uen cellule
sera vue comme une variable signée ou non-signée.

btw, que le char signed 'signed' ou 'unsigned' il me semble
bien qu'on accède à 8 bits en effet, enfin les signed char
ne font pas 9 bits (utiles) chez moi.

j'écrivais dans un post précédent qui n'ai pas apparu ici,
qu'il était évident que l'arithmétique associé à un entier
dépendait de son caractère signé ou non, pour autant son
*chargement* (mov al,[di] ou stosb ou lea al,offset) sont
uniques: i n'y a pas la "version qui plante avec un signé"
et celle qui "ne plante pas quelque soit le CRC puisque
c'est un unsigned là hein".


La norme guarantee qu'un accès à un unsigned char fonctionne.
Même si l'unsigned char n'a jamais été initialisé (mais
évidemment, la valeur que tu vois n'est pas déterminé dans ce
cas-là). La norme ne fait cette garantie pour aucune autre type.


ce qui consiste un point que Gabriel et toi n'avaient sciemment
pas cité (raisons diverses et inintéressantes ici).

en somme la norme dirait qu'une variable non initialisée est
non initialisée sauf quand dès fois elle a envie de l'être
tout en étant non déterminable - un paradigme à la Java aurait
été plus trivial voire ridicule en effet.

Sylvain.



Avatar
James Kanze
On Mar 9, 9:19 pm, Sylvain wrote:
James Kanze wrote on 09/03/2008 12:04:

On 8 mar, 23:40, Sylvain wrote:
James Kanze wrote on 07/03/2008 22:01:
Le type influence bien comment on y accède.


c'est en substance tout à fait contradictoire avec tes
positions du fil précédent.


Explique, si te plais. Je ne vois pas comment le type ne
pourrait pas influencer comment on accède aux objets---quand
j'accède à travers un lvalue de type char, par exemple, je
n'accède qu'aux huit bits, tandis qu'avec int... Et je suis
certain de ne jamais avoir dit le contraire.


contradictoire avec:


"À la mise sous tension, la mémoire contient effectivement"
"n'importe quoi. (Aussi, la plupart des contrôleurs dont je me"
"suis servi dans le temps prévoyaient bien une commande pour"
"écrire des valeurs erronées. Pour des motifs de test, si rien"
"d'autre. Mais le problème réel, c'est que jusqu'à la première"
"écriture, le contenu n'est pas défini, et il y a des chances"
"qu'il soit invalid.)"

la "mise sous tension" ne préjuge pas du fait qu'uen cellule
sera vue comme une variable signée ou non-signée.

btw, que le char signed 'signed' ou 'unsigned' il me semble
bien qu'on accède à 8 bits en effet, enfin les signed char ne
font pas 9 bits (utiles) chez moi.


Je ne suis pas trop sûr de ce qu'il est en C++, mais en C, la
garantie de pouvoir y accéder ne s'applique qu'au unsigned char.
Il y a aussi une exigence pour tous les types entiers que le
nombre de bits total soit le même pour les signed et les
unsigned.

Ça, c'est pour la norme. Comment une implémentation y arrive,
c'est autre chose. Dans le cas ci-dessus, évidemment,
l'implémentation a réelement que trois choix :

-- utiliser une instruction spéciale qui ignore les erreurs (en
supposant que ça existe) pour les accès char,

-- écrire elle-même toute la mémoire au moins une fois avant de
lancer l'application, ou

-- ne pas être conforme sur ce point.

Je crois que l'implémentation dont je me suis servi avait adopté
le troisième choix (mais pour être honnête vis-à-vis d'elle,
elle prédatait la norme C de pas mal d'années -- c'était donc à
elle de définir ce qu'elle voulais supporter ou non).

Enfin, bien vue. Je n'avais pas fait le rapprochement, et je
crois que dans la pratique, n'importe quelle implémentation qui
visait la conformance adopterait la deuxième option. (C'est ce
que nous avons fait, d'ailleurs, indirectement -- dans le code
d'initialisation, écrit en assembleur, on effectuait un test de
la mémoire qui effectivement écrivait tous les cellules.)

Reste le cas des Unisys MCP (encore en production et vendu
aujourd'hui), et peut-être d'autres (des machines Lisp, dans le
temps, mais ça m'étonne qu'on en trouve). Stimulé un peu par
Jean-Marc, j'ai réussi à trouver de la doc sur ces bêtes -- les
mots ont bien un bit de flag, qui pour un entier ou un flottant
doit avoir une valeur bien précise. Tu peux lire des octets
sans qu'il soit évalué, et même voir ce qu'il vaut de cette
façon, mais si tu essaies de lire un entier sur un mot (donc,
d'autre qu'un type char) ou un flottant, il y a bien un problème
si le bit n'a pas le bonne valeur. (Enfin, c'est une machine
assez exotique pour que j'imagine que beaucoup de programmes
qu'on croit portable n'y fonctionnent pas. Avec des choses
comme sizeof(int) == 6, INT_MAX == UINT_MAX == 2^39-1, malgré
les 48 bits. Et qui travaille encore aujourd'hui en EBCDIC par
défaut.)

j'écrivais dans un post précédent qui n'ai pas apparu ici,
qu'il était évident que l'arithmétique associé à un entier
dépendait de son caractère signé ou non, pour autant son
*chargement* (mov al,[di] ou stosb ou lea al,offset) sont
uniques: i n'y a pas la "version qui plante avec un signé"
et celle qui "ne plante pas quelque soit le CRC puisque
c'est un unsigned là hein".


Quand je parlais de différences en ce qui concerne la façon
qu'on accède aux valeurs, je pensais surtout aux différences
entre les accès byte et les accès mot. Sur le MCP, d'après le
peu que j'ai pû comprendre (je n'ai pas trouvé de doc
architecture ou hardware, seulement une description assez
détaillée des formats dans la doc ALGOL), l'accès char, unsigned
char et signed char doit se faire avec une instruction machine
qui ne prend pas en compte le tag (qui se trouve au niveau du
mot) ; les instructions d'accès mot, en revanche, doivent le
prendre bien en compte, mais je ne connais pas les détails.

--
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
Sylvain
James Kanze wrote on 10/03/2008 09:47:

Quand je parlais de différences en ce qui concerne la façon
qu'on accède aux valeurs, je pensais surtout aux différences
entre les accès byte et les accès mot. Sur le MCP, d'après le
peu que j'ai pû comprendre (je n'ai pas trouvé de doc
architecture ou hardware, seulement une description assez
détaillée des formats dans la doc ALGOL), l'accès char, unsigned
char et signed char doit se faire avec une instruction machine
qui ne prend pas en compte le tag (qui se trouve au niveau du
mot) ; les instructions d'accès mot, en revanche, doivent le
prendre bien en compte, mais je ne connais pas les détails.


moi non plus je ne connais pas ces détails et j'ai bcp de mal à
imaginer le tag magique lu dans certaines conditions uniquement.

un alignement peut être requis pour lire un mot - c'est assez
courant sur les petits procs - mais que les tests de parité ou
contrôle d'erreur dépendent de la taille mémoire accédée est
étonnant, d'autant plus que le proc lira souvent un mot complet
(demandera un mot complet au controleur mémoire) quand il traite
une opération d'un octet ... laissons cela aux électroniciens.

Sylvain.

Avatar
James Kanze
On Mar 11, 12:25 am, Sylvain wrote:
James Kanze wrote on 10/03/2008 09:47:

Quand je parlais de différences en ce qui concerne la façon
qu'on accède aux valeurs, je pensais surtout aux différences
entre les accès byte et les accès mot. Sur le MCP, d'après le
peu que j'ai pû comprendre (je n'ai pas trouvé de doc
architecture ou hardware, seulement une description assez
détaillée des formats dans la doc ALGOL), l'accès char, unsigned
char et signed char doit se faire avec une instruction machine
qui ne prend pas en compte le tag (qui se trouve au niveau du
mot) ; les instructions d'accès mot, en revanche, doivent le
prendre bien en compte, mais je ne connais pas les détails.


moi non plus je ne connais pas ces détails et j'ai bcp de mal à
imaginer le tag magique lu dans certaines conditions uniquement.


L'idée d'une architecture tagguée a eu une vogue, l'idée étant
de gerer un peu les types dans le hardware. Je crois que c'était
très courant dans les machines Lisp, par exemple (où le tag
indiquerait si le mot mémoire était un atome ou une cellule de
cons). Dans les années 1970, j'ai aussi entendu parler d'une
architecture avec un tag sur les indirections. Quand on lisait à
une adresse mémoire, si le tag était positionné, le processeur
utilisait la valeur comme une adresse d'indirection (avec les
désavantages évidents qu'avant d'écrire, il fallait lire, qu'il
fallait une instruction spéciale pour écrire des pointeurs --
c-à-d un store data et un store address instruction -- et qu'il
fallait une logique supplémentaire pour détecter des cycles --
sinon, tu avais une instruction machine qui n'en finissait
jamais).

Dans le cas du MCP, je n'ai pas le moindre idée comment ce tag
est utilisé ; seulement, la documentation dit qu'il y est ;
sur les 48 bits d'un mot, tu n'as normallement pas accès au bit
de poids forts (au moins au niveau langage évolué). Donc,
47 bits d'utiles. Si tu effectues des accès octet, en revanche,
c'est un bit comme un autre.

(Une autre particularité, c'est qu'au niveau du hardware, il n'y
a pas de distinction entre les flottants et les entiers. Le
format d'un mot, c'est:

bit 47 : le tag
bit 46 : le signe de la mantisse
bit 45 : le signe de l'exposant
bits 44-39 : la magnitude de l'exposant (base 8)
bits 38-0 : la magnitude de la mantisse

Avec la particularité qu'à l'encontre de tous les autres formats
flottants que j'ai vu, le virgule implicit se place à droit de
la mantisse, et non à gauche, et qu'il n'exige pas la
normalization. Ce qui fait que 0x000000000001 est une
représentation valable de 1.0 flottant -- et que plus
généralement, un « int », ce n'est qu'un flottant dont
l'exposant est 0. (Et puisque la machine n'a pas d'arithmetique
non-signée, on le simule en masquant le bit de signe, ce qui
fait que INT_MAX == UINT_MAX. 2^39 dans les deux cas, malgré
les 48 bits.)

Enfin, non seulement l'architecture est toujours au catalogue,
Unisys en sort de nouvelles modèles de temps en temps.

un alignement peut être requis pour lire un mot - c'est assez
courant sur les petits procs


Des petits procs, comme les IBM système z, les anciens Crays,
tous les Sparcs... En fait, les seules architectures que moi,
j'ai vues, où on n'avait pas besoin de respecter l'alignement,
c'est l'architecture Intel (probablement parce qu'au départ, il
n'avait que 8 bits).

- mais que les tests de parité ou
contrôle d'erreur dépendent de la taille mémoire accédée est
étonnant, d'autant plus que le proc lira souvent un mot complet
(demandera un mot complet au controleur mémoire) quand il traite
une opération d'un octet ... laissons cela aux électroniciens.


Aussi dans la passé, c'était assez courant que le contrôleur de
la mémoire ne supporte que les accès mot. Pour écrire un octet,
le processeur lisait un mot, insérait l'octet, et le réécrivait.

--
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
Jean-Marc Bourguet
James Kanze writes:

On Mar 11, 12:25 am, Sylvain wrote:
James Kanze wrote on 10/03/2008 09:47:

Quand je parlais de différences en ce qui concerne la façon
qu'on accède aux valeurs, je pensais surtout aux différences
entre les accès byte et les accès mot. Sur le MCP, d'après le
peu que j'ai pû comprendre (je n'ai pas trouvé de doc
architecture ou hardware, seulement une description assez
détaillée des formats dans la doc ALGOL), l'accès char, unsigned
char et signed char doit se faire avec une instruction machine
qui ne prend pas en compte le tag (qui se trouve au niveau du
mot) ; les instructions d'accès mot, en revanche, doivent le
prendre bien en compte, mais je ne connais pas les détails.


moi non plus je ne connais pas ces détails et j'ai bcp de mal à
imaginer le tag magique lu dans certaines conditions uniquement.


L'idée d'une architecture tagguée a eu une vogue, l'idée étant de gerer
un peu les types dans le hardware.


C'etait l'epoque ou l'objectif etait de reduire le "semantic gap" entre
hard et soft. On s'est rendu compte depuis que

- il y avait quand meme une difference semantique entre ce que
demandaient les langages et ce que fournissaient les machines, surtout
que les langages demandaient des choses differentes

- les instructions trop generiques etaient plus lentes pour les cas
particuliers rencontres en pratiques que des suites d'instructions
simples.


Je crois que c'était très courant dans les machines Lisp, par exemple (où
le tag indiquerait si le mot mémoire était un atome ou une cellule de
cons). Dans les années 1970, j'ai aussi entendu parler d'une architecture
avec un tag sur les indirections. Quand on lisait à une adresse mémoire,
si le tag était positionné, le processeur utilisait la valeur comme une
adresse d'indirection (avec les désavantages évidents qu'avant d'écrire,
il fallait lire, qu'il fallait une instruction spéciale pour écrire des
pointeurs -- c-à-d un store data et un store address instruction -- et
qu'il fallait une logique supplémentaire pour détecter des cycles --
sinon, tu avais une instruction machine qui n'en finissait jamais).


Le PDP-10 etait presque comme cela. En simplifie il y avait deux modes
d'adressage, le direct qui fonctionnait en utilisant directement l'adresse
construite par l'instruction (un champs d'adresse + un registre d'index) et
l'adressage indirect qui faisait la chose recursivement (y compris
l'utilisation du registre d'adresse). Le fait que les mots faisaient 36
bits et les adresses 18 aidait pas mal. Par la suite, ils ont etendu la
taille des adresses, je ne sais plus comment ce mode fonctionnait.

un alignement peut être requis pour lire un mot - c'est assez
courant sur les petits procs


Des petits procs, comme les IBM système z, les anciens Crays,
tous les Sparcs... En fait, les seules architectures que moi,
j'ai vues, où on n'avait pas besoin de respecter l'alignement,
c'est l'architecture Intel (probablement parce qu'au départ, il
n'avait que 8 bits).


Il me semblait que les machines IBM (que ce soit les descendant des 360 ou
les divers POWER) permettent l'adressage non aligne a (relativement) faible
cout. La raison que j'avais vu donnee etait que le COBOL en generait pas
mal. Mais je n'ai pas regarde precisement les manuels.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org



Avatar
Michel Decima
On Mar 11, 12:25 am, Sylvain wrote:

un alignement peut être requis pour lire un mot - c'est assez
courant sur les petits procs


Des petits procs, comme les IBM système z, les anciens Crays,
tous les Sparcs... En fait, les seules architectures que moi,
j'ai vues, où on n'avait pas besoin de respecter l'alignement,
c'est l'architecture Intel (probablement parce qu'au départ, il
n'avait que 8 bits).


Je crois que tu peux preciser "architecture Intel x86". Je travaille
en ce moment sur un ia64, il n'aime pas du tout les acces non alignes.


Avatar
James Kanze
On 11 mar, 11:10, Jean-Marc Bourguet wrote:
James Kanze writes:


[...]
Des petits procs, comme les IBM système z, les anciens Crays,
tous les Sparcs... En fait, les seules architectures que moi,
j'ai vues, où on n'avait pas besoin de respecter l'alignement,
c'est l'architecture Intel (probablement parce qu'au départ, il
n'avait que 8 bits).


Il me semblait que les machines IBM (que ce soit les
descendant des 360 ou les divers POWER) permettent l'adressage
non aligne a (relativement) faible cout. La raison que
j'avais vu donnee etait que le COBOL en generait pas mal.
Mais je n'ai pas regarde precisement les manuels.


J'avoue que mon expérence avec ce genre de processeur, c'est
plutôt chez les compatibles. Mais le Siemens BS2000 exigeait
bien un alignement de 4 (et peut-être même 8 pour les doubles),
et il se disait 100% compatibles.

--
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
Sylvain
James Kanze wrote on 11/03/2008 10:51:

un alignement peut être requis pour lire un mot - c'est assez
courant sur les petits procs


Des petits procs, comme les IBM système z, les anciens Crays,
tous les Sparcs... En fait, les seules architectures que moi,
j'ai vues, où on n'avait pas besoin de respecter l'alignement,
c'est l'architecture Intel (probablement parce qu'au départ, il
n'avait que 8 bits).


je pensais en effet à des procs Intel - imposant l'alignement -
comme les PXAnnn.
pardon d'avoir oublié les "0.001% of us" qui utilisent un Cray.

Sylvain.


Avatar
Jean-Marc Bourguet
Sylvain writes:

James Kanze wrote on 11/03/2008 10:51:

un alignement peut être requis pour lire un mot - c'est assez
courant sur les petits procs
Des petits procs, comme les IBM système z, les anciens Crays,

tous les Sparcs... En fait, les seules architectures que moi,
j'ai vues, où on n'avait pas besoin de respecter l'alignement,
c'est l'architecture Intel (probablement parce qu'au départ, il
n'avait que 8 bits).


je pensais en effet à des procs Intel - imposant l'alignement -
comme les PXAnnn.
pardon d'avoir oublié les "0.001% of us" qui utilisent un Cray.


Les Sparcs sont legerement plus repandues...

(J'ai acces a plus de machines avec des sparcs que d'autres processeurs).

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org



Avatar
James Kanze
On Mar 11, 10:37 pm, Sylvain wrote:
James Kanze wrote on 11/03/2008 10:51:

un alignement peut être requis pour lire un mot - c'est assez
courant sur les petits procs


Des petits procs, comme les IBM système z, les anciens Crays,
tous les Sparcs... En fait, les seules architectures que moi,
j'ai vues, où on n'avait pas besoin de respecter l'alignement,
c'est l'architecture Intel (probablement parce qu'au départ, il
n'avait que 8 bits).


je pensais en effet à des procs Intel - imposant l'alignement -
comme les PXAnnn.
pardon d'avoir oublié les "0.001% of us" qui utilisent un Cray.


Je vois plus souvent des Sparcs que les PXAnnn (dont j'entends
le nom pour le premier fois), et des Sparcs exigent bien
l'alignement. Mais j'ai cité des mainframes simplemnet parce que
tu as dit petits. En fait, je crois le fait de ne pas exiger
l'alignement est plutôt l'exception -- ça l'était dans la
passée, au moins (IBM RS6000, HP PA, Siemens BS2000, PDP-11,
Interdata 8/32 -- à vrai dire, il ne me viens pas à l'esprit de
l'essayer, puisque quand j'apprenais l'informatique, c'était la
règle).

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



1 2 3