Je n'arrive pas à comprendre pourquoi les entrées hexadécimales signées
ratent pour ffff.
Je suppose que la conversion hexa dans num_get<>() se
fait d'abord en non-signé puis il y a un check pour savoir si il y a
overflow dans le type signé (ce qui est le cas pour "ffff" en short).
Example: le programme suivant affiche "KO" sous gcc 3.4.3:
#include <iostream>
#include <sstream>
int main()
{
std::istringstream is("ffff");
short value;
if(!(is>>value))std::cerr<<"KO"<<std::endl;
}
Est ce une contrainte de formatage: le type nombre non signé a un nombre
limité de bytes à affiché alors que le type signé devrait garantir la
taille tu type ex: "ffffff...fe" pour -2 ?
Je n'arrive pas à comprendre pourquoi les entrées hexadécimales signées
ratent pour ffff.
Je suppose que la conversion hexa dans num_get<>() se
fait d'abord en non-signé puis il y a un check pour savoir si il y a
overflow dans le type signé (ce qui est le cas pour "ffff" en short).
Example: le programme suivant affiche "KO" sous gcc 3.4.3:
#include <iostream>
#include <sstream>
int main()
{
std::istringstream is("ffff");
short value;
if(!(is>>value))std::cerr<<"KO"<<std::endl;
}
Est ce une contrainte de formatage: le type nombre non signé a un nombre
limité de bytes à affiché alors que le type signé devrait garantir la
taille tu type ex: "ffffff...fe" pour -2 ?
Je n'arrive pas à comprendre pourquoi les entrées hexadécimales signées
ratent pour ffff.
Je suppose que la conversion hexa dans num_get<>() se
fait d'abord en non-signé puis il y a un check pour savoir si il y a
overflow dans le type signé (ce qui est le cas pour "ffff" en short).
Example: le programme suivant affiche "KO" sous gcc 3.4.3:
#include <iostream>
#include <sstream>
int main()
{
std::istringstream is("ffff");
short value;
if(!(is>>value))std::cerr<<"KO"<<std::endl;
}
Est ce une contrainte de formatage: le type nombre non signé a un nombre
limité de bytes à affiché alors que le type signé devrait garantir la
taille tu type ex: "ffffff...fe" pour -2 ?
Michael DOUBEZ a écrit :Je n'arrive pas à comprendre pourquoi les entrées hexadécimales
signées ratent pour ffff.
Pour la même raison que 65535 échouerait en décimal.Je suppose que la conversion hexa dans num_get<>() se fait d'abord en
non-signé puis il y a un check pour savoir si il y a overflow dans le
type signé (ce qui est le cas pour "ffff" en short).
Example: le programme suivant affiche "KO" sous gcc 3.4.3:
#include <iostream>
#include <sstream>
int main()
{
std::istringstream is("ffff");
short value;
if(!(is>>value))std::cerr<<"KO"<<std::endl;
}
Est ce une contrainte de formatage: le type nombre non signé a un
nombre limité de bytes à affiché alors que le type signé devrait
garantir la taille tu type ex: "ffffff...fe" pour -2 ?
Non, -2 en base 16 ne s'écrit pas ffffff...fe mais ... -2 ! (ou -0x2)
La base 16 n'est pas traitée différemment des autres bases, les
nombres négatifs doivent commencer par le signe moins.
Michael DOUBEZ a écrit :
Je n'arrive pas à comprendre pourquoi les entrées hexadécimales
signées ratent pour ffff.
Pour la même raison que 65535 échouerait en décimal.
Je suppose que la conversion hexa dans num_get<>() se fait d'abord en
non-signé puis il y a un check pour savoir si il y a overflow dans le
type signé (ce qui est le cas pour "ffff" en short).
Example: le programme suivant affiche "KO" sous gcc 3.4.3:
#include <iostream>
#include <sstream>
int main()
{
std::istringstream is("ffff");
short value;
if(!(is>>value))std::cerr<<"KO"<<std::endl;
}
Est ce une contrainte de formatage: le type nombre non signé a un
nombre limité de bytes à affiché alors que le type signé devrait
garantir la taille tu type ex: "ffffff...fe" pour -2 ?
Non, -2 en base 16 ne s'écrit pas ffffff...fe mais ... -2 ! (ou -0x2)
La base 16 n'est pas traitée différemment des autres bases, les
nombres négatifs doivent commencer par le signe moins.
Michael DOUBEZ a écrit :Je n'arrive pas à comprendre pourquoi les entrées hexadécimales
signées ratent pour ffff.
Pour la même raison que 65535 échouerait en décimal.Je suppose que la conversion hexa dans num_get<>() se fait d'abord en
non-signé puis il y a un check pour savoir si il y a overflow dans le
type signé (ce qui est le cas pour "ffff" en short).
Example: le programme suivant affiche "KO" sous gcc 3.4.3:
#include <iostream>
#include <sstream>
int main()
{
std::istringstream is("ffff");
short value;
if(!(is>>value))std::cerr<<"KO"<<std::endl;
}
Est ce une contrainte de formatage: le type nombre non signé a un
nombre limité de bytes à affiché alors que le type signé devrait
garantir la taille tu type ex: "ffffff...fe" pour -2 ?
Non, -2 en base 16 ne s'écrit pas ffffff...fe mais ... -2 ! (ou -0x2)
La base 16 n'est pas traitée différemment des autres bases, les
nombres négatifs doivent commencer par le signe moins.
Pourtant:
short d=-1;
std::cout<<std::hex<<d<<std::endl;
écrit:
ffff
et non pas -1
Pourtant:
short d=-1;
std::cout<<std::hex<<d<<std::endl;
écrit:
ffff
et non pas -1
Pourtant:
short d=-1;
std::cout<<std::hex<<d<<std::endl;
écrit:
ffff
et non pas -1
Je n'arrive pas à comprendre pourquoi les entrées
hexadécimales signées ratent pour ffff. Je suppose que la
conversion hexa dans num_get<>() se fait d'abord en non-signé
puis il y a un check pour savoir si il y a overflow dans le
type signé (ce qui est le cas pour "ffff" en short).
Example: le programme suivant affiche "KO" sous gcc 3.4.3:
#include <iostream>
#include <sstream>
int main()
{
std::istringstream is("ffff");
short value;
if(!(is>>value))std::cerr<<"KO"<<std::endl;
}
Est ce une contrainte de formatage: le type nombre non signé a
un nombre limité de bytes à affiché alors que le type signé
devrait garantir la taille tu type ex: "ffffff...fe" pour -2 ?
Je ne vois que ça.
Est ce qu'il y une référence à cela dans le standard
(§27.6.1.2?) ?
Je n'arrive pas à comprendre pourquoi les entrées
hexadécimales signées ratent pour ffff. Je suppose que la
conversion hexa dans num_get<>() se fait d'abord en non-signé
puis il y a un check pour savoir si il y a overflow dans le
type signé (ce qui est le cas pour "ffff" en short).
Example: le programme suivant affiche "KO" sous gcc 3.4.3:
#include <iostream>
#include <sstream>
int main()
{
std::istringstream is("ffff");
short value;
if(!(is>>value))std::cerr<<"KO"<<std::endl;
}
Est ce une contrainte de formatage: le type nombre non signé a
un nombre limité de bytes à affiché alors que le type signé
devrait garantir la taille tu type ex: "ffffff...fe" pour -2 ?
Je ne vois que ça.
Est ce qu'il y une référence à cela dans le standard
(§27.6.1.2?) ?
Je n'arrive pas à comprendre pourquoi les entrées
hexadécimales signées ratent pour ffff. Je suppose que la
conversion hexa dans num_get<>() se fait d'abord en non-signé
puis il y a un check pour savoir si il y a overflow dans le
type signé (ce qui est le cas pour "ffff" en short).
Example: le programme suivant affiche "KO" sous gcc 3.4.3:
#include <iostream>
#include <sstream>
int main()
{
std::istringstream is("ffff");
short value;
if(!(is>>value))std::cerr<<"KO"<<std::endl;
}
Est ce une contrainte de formatage: le type nombre non signé a
un nombre limité de bytes à affiché alors que le type signé
devrait garantir la taille tu type ex: "ffffff...fe" pour -2 ?
Je ne vois que ça.
Est ce qu'il y une référence à cela dans le standard
(§27.6.1.2?) ?
Michael DOUBEZ writes:Pourtant:
short d=-1;
std::cout<<std::hex<<d<<std::endl;
écrit:
ffff
et non pas -1
hex implique que l'argument est converti en unsigned (et oui, c'est defini
en fonction de "%x" de printf et "%x" prend un argument unsigned).
Michael DOUBEZ <michael.doubez@free.fr> writes:
Pourtant:
short d=-1;
std::cout<<std::hex<<d<<std::endl;
écrit:
ffff
et non pas -1
hex implique que l'argument est converti en unsigned (et oui, c'est defini
en fonction de "%x" de printf et "%x" prend un argument unsigned).
Michael DOUBEZ writes:Pourtant:
short d=-1;
std::cout<<std::hex<<d<<std::endl;
écrit:
ffff
et non pas -1
hex implique que l'argument est converti en unsigned (et oui, c'est defini
en fonction de "%x" de printf et "%x" prend un argument unsigned).
On Feb 10, 1:37 pm, Michael DOUBEZ wrote:Je n'arrive pas à comprendre pourquoi les entrées
hexadécimales signées ratent pour ffff. Je suppose que la
conversion hexa dans num_get<>() se fait d'abord en non-signé
puis il y a un check pour savoir si il y a overflow dans le
type signé (ce qui est le cas pour "ffff" en short).
Comme d'autres ont déjà dit, 0xFFFF a une valeur positive qui ne
tient pas dans un short.
Est ce qu'il y une référence à cela dans le standard
(§27.6.1.2?) ?
§27.6.1.2 renvoie à §22.2.2.1 (la facette num_put), qui lui
renvoie à fscanf de la norme C. Qui dit (d'une façon globale,
pour toutes les conversions) « [...], the result of the
conversion is placed in the object pointed to by the first
argument following the format argument that has not already
received a conversion result. If this object does not have an
appropriate type, or if the result of the conversion cannot be
represented in the object, the behavior is undefined. »
La brouillon de comité pour C++0x a modifié §22.2.2.1 pour
renvoyer à strtoll (qui a un comportement défini quelque soit
les entrées), avec une gestion d'erreur précisée ; dans le cas
de débordement (comme ici), il doit stocker la valeur maximum
du type (ou valeur minimum, si la valeur lue est négative) et
positionner le failbit (et donc, l'entrée échoue). Ce qui
correspond plus ou moins au comportement des bonnes
implémentations déjà. (Je ne suis pas sûr en ce qui concerne le
stockage de la valeur -- il y a aussi une tradition qu'en cas
d'erreur, l'objet qu'on lit n'est pas modifié.)
On Feb 10, 1:37 pm, Michael DOUBEZ <michael.dou...@free.fr> wrote:
Je n'arrive pas à comprendre pourquoi les entrées
hexadécimales signées ratent pour ffff. Je suppose que la
conversion hexa dans num_get<>() se fait d'abord en non-signé
puis il y a un check pour savoir si il y a overflow dans le
type signé (ce qui est le cas pour "ffff" en short).
Comme d'autres ont déjà dit, 0xFFFF a une valeur positive qui ne
tient pas dans un short.
Est ce qu'il y une référence à cela dans le standard
(§27.6.1.2?) ?
§27.6.1.2 renvoie à §22.2.2.1 (la facette num_put), qui lui
renvoie à fscanf de la norme C. Qui dit (d'une façon globale,
pour toutes les conversions) « [...], the result of the
conversion is placed in the object pointed to by the first
argument following the format argument that has not already
received a conversion result. If this object does not have an
appropriate type, or if the result of the conversion cannot be
represented in the object, the behavior is undefined. »
La brouillon de comité pour C++0x a modifié §22.2.2.1 pour
renvoyer à strtoll (qui a un comportement défini quelque soit
les entrées), avec une gestion d'erreur précisée ; dans le cas
de débordement (comme ici), il doit stocker la valeur maximum
du type (ou valeur minimum, si la valeur lue est négative) et
positionner le failbit (et donc, l'entrée échoue). Ce qui
correspond plus ou moins au comportement des bonnes
implémentations déjà. (Je ne suis pas sûr en ce qui concerne le
stockage de la valeur -- il y a aussi une tradition qu'en cas
d'erreur, l'objet qu'on lit n'est pas modifié.)
On Feb 10, 1:37 pm, Michael DOUBEZ wrote:Je n'arrive pas à comprendre pourquoi les entrées
hexadécimales signées ratent pour ffff. Je suppose que la
conversion hexa dans num_get<>() se fait d'abord en non-signé
puis il y a un check pour savoir si il y a overflow dans le
type signé (ce qui est le cas pour "ffff" en short).
Comme d'autres ont déjà dit, 0xFFFF a une valeur positive qui ne
tient pas dans un short.
Est ce qu'il y une référence à cela dans le standard
(§27.6.1.2?) ?
§27.6.1.2 renvoie à §22.2.2.1 (la facette num_put), qui lui
renvoie à fscanf de la norme C. Qui dit (d'une façon globale,
pour toutes les conversions) « [...], the result of the
conversion is placed in the object pointed to by the first
argument following the format argument that has not already
received a conversion result. If this object does not have an
appropriate type, or if the result of the conversion cannot be
represented in the object, the behavior is undefined. »
La brouillon de comité pour C++0x a modifié §22.2.2.1 pour
renvoyer à strtoll (qui a un comportement défini quelque soit
les entrées), avec une gestion d'erreur précisée ; dans le cas
de débordement (comme ici), il doit stocker la valeur maximum
du type (ou valeur minimum, si la valeur lue est négative) et
positionner le failbit (et donc, l'entrée échoue). Ce qui
correspond plus ou moins au comportement des bonnes
implémentations déjà. (Je ne suis pas sûr en ce qui concerne le
stockage de la valeur -- il y a aussi une tradition qu'en cas
d'erreur, l'objet qu'on lit n'est pas modifié.)
Jean-Marc Bourguet a écrit :
> Michael DOUBEZ writes:
>
>> Pourtant:
>> short d=-1;
>> std::cout<<std::hex<<d<<std::endl;
>>
>> écrit:
>> ffff
>>
>> et non pas -1
> hex implique que l'argument est converti en unsigned (et oui, c'est defini
> en fonction de "%x" de printf et "%x" prend un argument unsigned).
Et comment ça se fait qu'en entrée c'est l'inverse : ffff ne fonctionne
pas mais -1 oui ? L'incohérence est-elle au niveau ostream/istream ou
printf/scanf ?
Jean-Marc Bourguet a écrit :
> Michael DOUBEZ <michael.doubez@free.fr> writes:
>
>> Pourtant:
>> short d=-1;
>> std::cout<<std::hex<<d<<std::endl;
>>
>> écrit:
>> ffff
>>
>> et non pas -1
> hex implique que l'argument est converti en unsigned (et oui, c'est defini
> en fonction de "%x" de printf et "%x" prend un argument unsigned).
Et comment ça se fait qu'en entrée c'est l'inverse : ffff ne fonctionne
pas mais -1 oui ? L'incohérence est-elle au niveau ostream/istream ou
printf/scanf ?
Jean-Marc Bourguet a écrit :
> Michael DOUBEZ writes:
>
>> Pourtant:
>> short d=-1;
>> std::cout<<std::hex<<d<<std::endl;
>>
>> écrit:
>> ffff
>>
>> et non pas -1
> hex implique que l'argument est converti en unsigned (et oui, c'est defini
> en fonction de "%x" de printf et "%x" prend un argument unsigned).
Et comment ça se fait qu'en entrée c'est l'inverse : ffff ne fonctionne
pas mais -1 oui ? L'incohérence est-elle au niveau ostream/istream ou
printf/scanf ?
James Kanze wrote:
> On Feb 10, 1:37 pm, Michael DOUBEZ wrote:
>> Je n'arrive pas à comprendre pourquoi les entrées
>> hexadécimales signées ratent pour ffff. Je suppose que la
>> conversion hexa dans num_get<>() se fait d'abord en non-signé
>> puis il y a un check pour savoir si il y a overflow dans le
>> type signé (ce qui est le cas pour "ffff" en short).
[snip]
> Comme d'autres ont déjà dit, 0xFFFF a une valeur positive
> qui ne tient pas dans un short.
Mon erreur consistait a considérer le contenu bit de -1 en
short et pas la valeur.
>> Est ce qu'il y une référence à cela dans le standard
>> (§27.6.1.2?) ?
> §27.6.1.2 renvoie à §22.2.2.1 (la facette num_put), qui lui
> renvoie à fscanf de la norme C. Qui dit (d'une façon globale,
> pour toutes les conversions) « [...], the result of the
> conversion is placed in the object pointed to by the first
> argument following the format argument that has not already
> received a conversion result. If this object does not have an
> appropriate type, or if the result of the conversion cannot be
> represented in the object, the behavior is undefined. »
Dans ce cas, pour fscanf, c'est transparent puisque le passage
de paramètre perd l'information de type des pointeurs.
Je peux donc faire:
short val;
scanf("%hx",&val);
Je suppose que c'est formellement un comportement indéfini
mais je vois peu de différence avec:
short val;
unsigned short val_input;
scanf("%hx",&val_input);
val=unsigned short(val_input)
si je sais que la représentation bit correspond.
J'ai regardé dans 22.2.2.1.2, et si je comprend bien, ça veux
dire que toutes les opération font une conversion implicite en
non-signé dès que basefield n'est plus 0.
> La brouillon de comité pour C++0x a modifié §22.2.2.1 pour
> renvoyer à strtoll (qui a un comportement défini quelque soit
> les entrées), avec une gestion d'erreur précisée ; dans le cas
> de débordement (comme ici), il doit stocker la valeur maximum
> du type (ou valeur minimum, si la valeur lue est négative) et
> positionner le failbit (et donc, l'entrée échoue). Ce qui
> correspond plus ou moins au comportement des bonnes
> implémentations déjà. (Je ne suis pas sûr en ce qui concerne le
> stockage de la valeur -- il y a aussi une tradition qu'en cas
> d'erreur, l'objet qu'on lit n'est pas modifié.)
Sous gcc3.4.3 le paramètre n'est pas modifié et failbit est
positionné.
Dès que j'ai mis le basefield de ma stream à ios::hex, mes
tests unitaires se sont mis à m'insulter. J'utilisais des
(i/o)stream_iterator<short>() et l'absence de réversibilité
m'a surpris. J'utilise donc des itérateurs <unsigned short> à
la place. Mais, dans un cas de static_assert du value_type de
mes itérateurs ou de metaparamètre, cette conversion serait
énervante.
James Kanze wrote:
> On Feb 10, 1:37 pm, Michael DOUBEZ <michael.dou...@free.fr> wrote:
>> Je n'arrive pas à comprendre pourquoi les entrées
>> hexadécimales signées ratent pour ffff. Je suppose que la
>> conversion hexa dans num_get<>() se fait d'abord en non-signé
>> puis il y a un check pour savoir si il y a overflow dans le
>> type signé (ce qui est le cas pour "ffff" en short).
[snip]
> Comme d'autres ont déjà dit, 0xFFFF a une valeur positive
> qui ne tient pas dans un short.
Mon erreur consistait a considérer le contenu bit de -1 en
short et pas la valeur.
>> Est ce qu'il y une référence à cela dans le standard
>> (§27.6.1.2?) ?
> §27.6.1.2 renvoie à §22.2.2.1 (la facette num_put), qui lui
> renvoie à fscanf de la norme C. Qui dit (d'une façon globale,
> pour toutes les conversions) « [...], the result of the
> conversion is placed in the object pointed to by the first
> argument following the format argument that has not already
> received a conversion result. If this object does not have an
> appropriate type, or if the result of the conversion cannot be
> represented in the object, the behavior is undefined. »
Dans ce cas, pour fscanf, c'est transparent puisque le passage
de paramètre perd l'information de type des pointeurs.
Je peux donc faire:
short val;
scanf("%hx",&val);
Je suppose que c'est formellement un comportement indéfini
mais je vois peu de différence avec:
short val;
unsigned short val_input;
scanf("%hx",&val_input);
val=unsigned short(val_input)
si je sais que la représentation bit correspond.
J'ai regardé dans 22.2.2.1.2, et si je comprend bien, ça veux
dire que toutes les opération font une conversion implicite en
non-signé dès que basefield n'est plus 0.
> La brouillon de comité pour C++0x a modifié §22.2.2.1 pour
> renvoyer à strtoll (qui a un comportement défini quelque soit
> les entrées), avec une gestion d'erreur précisée ; dans le cas
> de débordement (comme ici), il doit stocker la valeur maximum
> du type (ou valeur minimum, si la valeur lue est négative) et
> positionner le failbit (et donc, l'entrée échoue). Ce qui
> correspond plus ou moins au comportement des bonnes
> implémentations déjà. (Je ne suis pas sûr en ce qui concerne le
> stockage de la valeur -- il y a aussi une tradition qu'en cas
> d'erreur, l'objet qu'on lit n'est pas modifié.)
Sous gcc3.4.3 le paramètre n'est pas modifié et failbit est
positionné.
Dès que j'ai mis le basefield de ma stream à ios::hex, mes
tests unitaires se sont mis à m'insulter. J'utilisais des
(i/o)stream_iterator<short>() et l'absence de réversibilité
m'a surpris. J'utilise donc des itérateurs <unsigned short> à
la place. Mais, dans un cas de static_assert du value_type de
mes itérateurs ou de metaparamètre, cette conversion serait
énervante.
James Kanze wrote:
> On Feb 10, 1:37 pm, Michael DOUBEZ wrote:
>> Je n'arrive pas à comprendre pourquoi les entrées
>> hexadécimales signées ratent pour ffff. Je suppose que la
>> conversion hexa dans num_get<>() se fait d'abord en non-signé
>> puis il y a un check pour savoir si il y a overflow dans le
>> type signé (ce qui est le cas pour "ffff" en short).
[snip]
> Comme d'autres ont déjà dit, 0xFFFF a une valeur positive
> qui ne tient pas dans un short.
Mon erreur consistait a considérer le contenu bit de -1 en
short et pas la valeur.
>> Est ce qu'il y une référence à cela dans le standard
>> (§27.6.1.2?) ?
> §27.6.1.2 renvoie à §22.2.2.1 (la facette num_put), qui lui
> renvoie à fscanf de la norme C. Qui dit (d'une façon globale,
> pour toutes les conversions) « [...], the result of the
> conversion is placed in the object pointed to by the first
> argument following the format argument that has not already
> received a conversion result. If this object does not have an
> appropriate type, or if the result of the conversion cannot be
> represented in the object, the behavior is undefined. »
Dans ce cas, pour fscanf, c'est transparent puisque le passage
de paramètre perd l'information de type des pointeurs.
Je peux donc faire:
short val;
scanf("%hx",&val);
Je suppose que c'est formellement un comportement indéfini
mais je vois peu de différence avec:
short val;
unsigned short val_input;
scanf("%hx",&val_input);
val=unsigned short(val_input)
si je sais que la représentation bit correspond.
J'ai regardé dans 22.2.2.1.2, et si je comprend bien, ça veux
dire que toutes les opération font une conversion implicite en
non-signé dès que basefield n'est plus 0.
> La brouillon de comité pour C++0x a modifié §22.2.2.1 pour
> renvoyer à strtoll (qui a un comportement défini quelque soit
> les entrées), avec une gestion d'erreur précisée ; dans le cas
> de débordement (comme ici), il doit stocker la valeur maximum
> du type (ou valeur minimum, si la valeur lue est négative) et
> positionner le failbit (et donc, l'entrée échoue). Ce qui
> correspond plus ou moins au comportement des bonnes
> implémentations déjà. (Je ne suis pas sûr en ce qui concerne le
> stockage de la valeur -- il y a aussi une tradition qu'en cas
> d'erreur, l'objet qu'on lit n'est pas modifié.)
Sous gcc3.4.3 le paramètre n'est pas modifié et failbit est
positionné.
Dès que j'ai mis le basefield de ma stream à ios::hex, mes
tests unitaires se sont mis à m'insulter. J'utilisais des
(i/o)stream_iterator<short>() et l'absence de réversibilité
m'a surpris. J'utilise donc des itérateurs <unsigned short> à
la place. Mais, dans un cas de static_assert du value_type de
mes itérateurs ou de metaparamètre, cette conversion serait
énervante.