Salut.
J'ai un de mes collègues qui est tombé sur ce qui ressemble à un bug de
Visual.net (non présent dans Visual 6), mais bon, c'est peut-être bettement
que ce qu'il a fait à un comportement indéfini, donc je préfère demander ici
avant éventuellement de reporter le bug à qui de droit.
Voila son mail original:
========================= > Bonjour,
.NET a un gros problème avec les décalages de valeurs signées en release.
En debug le code est nickel, mais en release il compile n'importe quoi.
C'est un PB que j'ai eu sur edAudio Hier, ((nValue>>31)^nValue) donne une
valeur approchée de abs(nValue), mais sans appel de fonctions et sans test.
Salut.
J'ai un de mes collègues qui est tombé sur ce qui ressemble à un bug de
Visual.net (non présent dans Visual 6), mais bon, c'est peut-être bettement
que ce qu'il a fait à un comportement indéfini, donc je préfère demander ici
avant éventuellement de reporter le bug à qui de droit.
Voila son mail original:
========================= > Bonjour,
.NET a un gros problème avec les décalages de valeurs signées en release.
En debug le code est nickel, mais en release il compile n'importe quoi.
C'est un PB que j'ai eu sur edAudio Hier, ((nValue>>31)^nValue) donne une
valeur approchée de abs(nValue), mais sans appel de fonctions et sans test.
Salut.
J'ai un de mes collègues qui est tombé sur ce qui ressemble à un bug de
Visual.net (non présent dans Visual 6), mais bon, c'est peut-être bettement
que ce qu'il a fait à un comportement indéfini, donc je préfère demander ici
avant éventuellement de reporter le bug à qui de droit.
Voila son mail original:
========================= > Bonjour,
.NET a un gros problème avec les décalages de valeurs signées en release.
En debug le code est nickel, mais en release il compile n'importe quoi.
C'est un PB que j'ai eu sur edAudio Hier, ((nValue>>31)^nValue) donne une
valeur approchée de abs(nValue), mais sans appel de fonctions et sans test.
Salut.
[...]
Alors, bug, ou bien résultat d'un comportement indéfini ???
Je pencherais pour un bug de l'optimiseur, mais avec la prudence
Salut.
[...]
Alors, bug, ou bien résultat d'un comportement indéfini ???
Je pencherais pour un bug de l'optimiseur, mais avec la prudence
Salut.
[...]
Alors, bug, ou bien résultat d'un comportement indéfini ???
Je pencherais pour un bug de l'optimiseur, mais avec la prudence
Mickael Pointier wrote:Salut.
J'ai un de mes collègues qui est tombé sur ce qui ressemble à un bug de
Visual.net (non présent dans Visual 6), mais bon, c'est peut-être bettement
que ce qu'il a fait à un comportement indéfini, donc je préfère demander ici
avant éventuellement de reporter le bug à qui de droit.
Voila son mail original:
========================= >> Bonjour,
.NET a un gros problème avec les décalages de valeurs signées en release.
En debug le code est nickel, mais en release il compile n'importe quoi.
C'est un PB que j'ai eu sur edAudio Hier, ((nValue>>31)^nValue) donne une
valeur approchée de abs(nValue), mais sans appel de fonctions et sans test.
Personnellement, je préfère abs(nValue), et je ne suis même pas certain
des performances. J'ai donc fait quelques tests :
Dev C++/gcc :
Abs : 0.719
Truc sur les bits : 0.328
Visual C++ :
Abs : 0.312
Truc sur les bits : 0.297
Sur visual C++ (qui semble l'environnement cible), la différence
vaut-elle le coup (surtout que abs donne une valeur correcte) ?
D'autant plus que la norme n'indique rien sur la valeur obtenue :
The value of E1 >> E2 is E1 rightshifted E2 bit positions. If E1 has an
unsigned type or if E1 has a signed type and a nonnegative value, the
value of the result is the integral part of the quotient of E1 divided
by the quantity 2 raised to the power E2. If E1 has a signed type and a
negative value, the resulting value is implementationdefined.
Ne pas confondre bug et non-conformité à la norme. Le bug est
Mais il doit y avoir une seule valeur obtenue. Qu'elle soit différente
en debug et en release me semble surprenant, mauvais en terme de QoI,
mais correct par rapport à la norme (debug et release sont deux
implémentations différentes...). Qu'elle soit différente entre :
int nResult = (nValue>>31)^nValue;
nResult>>=4;
Et :
int nResult = ((nValue>>31)^nValue);
printf("Resultat %dn",nResult);
nResult>>=4;
Me semble incorrect.
Mais éventuellement explicable par un bug dans l'optimiseur sur une
Mickael Pointier wrote:
Salut.
J'ai un de mes collègues qui est tombé sur ce qui ressemble à un bug de
Visual.net (non présent dans Visual 6), mais bon, c'est peut-être bettement
que ce qu'il a fait à un comportement indéfini, donc je préfère demander ici
avant éventuellement de reporter le bug à qui de droit.
Voila son mail original:
========================= >> Bonjour,
.NET a un gros problème avec les décalages de valeurs signées en release.
En debug le code est nickel, mais en release il compile n'importe quoi.
C'est un PB que j'ai eu sur edAudio Hier, ((nValue>>31)^nValue) donne une
valeur approchée de abs(nValue), mais sans appel de fonctions et sans test.
Personnellement, je préfère abs(nValue), et je ne suis même pas certain
des performances. J'ai donc fait quelques tests :
Dev C++/gcc :
Abs : 0.719
Truc sur les bits : 0.328
Visual C++ :
Abs : 0.312
Truc sur les bits : 0.297
Sur visual C++ (qui semble l'environnement cible), la différence
vaut-elle le coup (surtout que abs donne une valeur correcte) ?
D'autant plus que la norme n'indique rien sur la valeur obtenue :
The value of E1 >> E2 is E1 rightshifted E2 bit positions. If E1 has an
unsigned type or if E1 has a signed type and a nonnegative value, the
value of the result is the integral part of the quotient of E1 divided
by the quantity 2 raised to the power E2. If E1 has a signed type and a
negative value, the resulting value is implementationdefined.
Ne pas confondre bug et non-conformité à la norme. Le bug est
Mais il doit y avoir une seule valeur obtenue. Qu'elle soit différente
en debug et en release me semble surprenant, mauvais en terme de QoI,
mais correct par rapport à la norme (debug et release sont deux
implémentations différentes...). Qu'elle soit différente entre :
int nResult = (nValue>>31)^nValue;
nResult>>=4;
Et :
int nResult = ((nValue>>31)^nValue);
printf("Resultat %dn",nResult);
nResult>>=4;
Me semble incorrect.
Mais éventuellement explicable par un bug dans l'optimiseur sur une
Mickael Pointier wrote:Salut.
J'ai un de mes collègues qui est tombé sur ce qui ressemble à un bug de
Visual.net (non présent dans Visual 6), mais bon, c'est peut-être bettement
que ce qu'il a fait à un comportement indéfini, donc je préfère demander ici
avant éventuellement de reporter le bug à qui de droit.
Voila son mail original:
========================= >> Bonjour,
.NET a un gros problème avec les décalages de valeurs signées en release.
En debug le code est nickel, mais en release il compile n'importe quoi.
C'est un PB que j'ai eu sur edAudio Hier, ((nValue>>31)^nValue) donne une
valeur approchée de abs(nValue), mais sans appel de fonctions et sans test.
Personnellement, je préfère abs(nValue), et je ne suis même pas certain
des performances. J'ai donc fait quelques tests :
Dev C++/gcc :
Abs : 0.719
Truc sur les bits : 0.328
Visual C++ :
Abs : 0.312
Truc sur les bits : 0.297
Sur visual C++ (qui semble l'environnement cible), la différence
vaut-elle le coup (surtout que abs donne une valeur correcte) ?
D'autant plus que la norme n'indique rien sur la valeur obtenue :
The value of E1 >> E2 is E1 rightshifted E2 bit positions. If E1 has an
unsigned type or if E1 has a signed type and a nonnegative value, the
value of the result is the integral part of the quotient of E1 divided
by the quantity 2 raised to the power E2. If E1 has a signed type and a
negative value, the resulting value is implementationdefined.
Ne pas confondre bug et non-conformité à la norme. Le bug est
Mais il doit y avoir une seule valeur obtenue. Qu'elle soit différente
en debug et en release me semble surprenant, mauvais en terme de QoI,
mais correct par rapport à la norme (debug et release sont deux
implémentations différentes...). Qu'elle soit différente entre :
int nResult = (nValue>>31)^nValue;
nResult>>=4;
Et :
int nResult = ((nValue>>31)^nValue);
printf("Resultat %dn",nResult);
nResult>>=4;
Me semble incorrect.
Mais éventuellement explicable par un bug dans l'optimiseur sur une
Testez par vous même:
#include <stdio.h>
#include <conio.h>
void main()
{
int nValue;
printf("entrey la valeur -1024 et comparez le resultat entre debug et
releasen");
scanf("%d",&nValue);
int nResult = ((nValue>>31)^nValue)>>4;
printf("Resultat %dn",nResult);
}
========================= >
Testez par vous même:
#include <stdio.h>
#include <conio.h>
void main()
{
int nValue;
printf("entrey la valeur -1024 et comparez le resultat entre debug et
releasen");
scanf("%d",&nValue);
int nResult = ((nValue>>31)^nValue)>>4;
printf("Resultat %dn",nResult);
}
========================= >
Testez par vous même:
#include <stdio.h>
#include <conio.h>
void main()
{
int nValue;
printf("entrey la valeur -1024 et comparez le resultat entre debug et
releasen");
scanf("%d",&nValue);
int nResult = ((nValue>>31)^nValue)>>4;
printf("Resultat %dn",nResult);
}
========================= >
Testez par vous même:
#include <stdio.h>
#include <conio.h>
void main()
{
int nValue;
printf("entrey la valeur -1024 et comparez le resultat entre debug et
releasen");
scanf("%d",&nValue);
int nResult = ((nValue>>31)^nValue)>>4;
printf("Resultat %dn",nResult);
}
========================= >>
Je pencherais pour un comportement non défini, et non pour un bug.
La norme defini-t-elle les valeurs signées binaires ? la rotation de ces
memes valeurs ?
Ne pouvant le tester par moi-même ( VC6, seulement), une solution serait de
caster en unsigned :
int nResult = (( ((unsigned int) nValue) >>31)^nValue)>>4;
Extrait du post de Loïc Joly (et de C++98 5.8.3):
Testez par vous même:
#include <stdio.h>
#include <conio.h>
void main()
{
int nValue;
printf("entrey la valeur -1024 et comparez le resultat entre debug et
releasen");
scanf("%d",&nValue);
int nResult = ((nValue>>31)^nValue)>>4;
printf("Resultat %dn",nResult);
}
========================= >>
Je pencherais pour un comportement non défini, et non pour un bug.
La norme defini-t-elle les valeurs signées binaires ? la rotation de ces
memes valeurs ?
Ne pouvant le tester par moi-même ( VC6, seulement), une solution serait de
caster en unsigned :
int nResult = (( ((unsigned int) nValue) >>31)^nValue)>>4;
Extrait du post de Loïc Joly (et de C++98 5.8.3):
Testez par vous même:
#include <stdio.h>
#include <conio.h>
void main()
{
int nValue;
printf("entrey la valeur -1024 et comparez le resultat entre debug et
releasen");
scanf("%d",&nValue);
int nResult = ((nValue>>31)^nValue)>>4;
printf("Resultat %dn",nResult);
}
========================= >>
Je pencherais pour un comportement non défini, et non pour un bug.
La norme defini-t-elle les valeurs signées binaires ? la rotation de ces
memes valeurs ?
Ne pouvant le tester par moi-même ( VC6, seulement), une solution serait de
caster en unsigned :
int nResult = (( ((unsigned int) nValue) >>31)^nValue)>>4;
Extrait du post de Loïc Joly (et de C++98 5.8.3):
Testez par vous même:
#include <stdio.h>
#include <conio.h>
void main()
{
int nValue;
printf("entrey la valeur -1024 et comparez le resultat entre
debug et releasen");
scanf("%d",&nValue);
int nResult = ((nValue>>31)^nValue)>>4;
printf("Resultat %dn",nResult);
}
========================= >>
Je pencherais pour un comportement non défini, et non pour un bug.
La norme defini-t-elle les valeurs signées binaires ? la rotation de
ces memes valeurs ?
Ne pouvant le tester par moi-même ( VC6, seulement), une solution
serait de caster en unsigned :
int nResult = (( ((unsigned int) nValue) >>31)^nValue)>>4;
Testez par vous même:
#include <stdio.h>
#include <conio.h>
void main()
{
int nValue;
printf("entrey la valeur -1024 et comparez le resultat entre
debug et releasen");
scanf("%d",&nValue);
int nResult = ((nValue>>31)^nValue)>>4;
printf("Resultat %dn",nResult);
}
========================= >>
Je pencherais pour un comportement non défini, et non pour un bug.
La norme defini-t-elle les valeurs signées binaires ? la rotation de
ces memes valeurs ?
Ne pouvant le tester par moi-même ( VC6, seulement), une solution
serait de caster en unsigned :
int nResult = (( ((unsigned int) nValue) >>31)^nValue)>>4;
Testez par vous même:
#include <stdio.h>
#include <conio.h>
void main()
{
int nValue;
printf("entrey la valeur -1024 et comparez le resultat entre
debug et releasen");
scanf("%d",&nValue);
int nResult = ((nValue>>31)^nValue)>>4;
printf("Resultat %dn",nResult);
}
========================= >>
Je pencherais pour un comportement non défini, et non pour un bug.
La norme defini-t-elle les valeurs signées binaires ? la rotation de
ces memes valeurs ?
Ne pouvant le tester par moi-même ( VC6, seulement), une solution
serait de caster en unsigned :
int nResult = (( ((unsigned int) nValue) >>31)^nValue)>>4;
Loïc Joly typa:Mickael Pointier wrote:
The value of E1 >> E2 is E1 rightshifted E2 bit positions. If E1 has
an unsigned type or if E1 has a signed type and a nonnegative value,
the value of the result is the integral part of the quotient of E1
divided by the quantity 2 raised to the power E2. If E1 has a signed
type and a negative value, the resulting value is
implementationdefined.
Ne pas confondre bug et non-conformité à la norme. Le bug est
pratiquement un "délit commercial", à juger par rapport à un contrat.
La norme dit "implementation defined", l'implémentation documente :
</MSDN VS.NET 2003 C++ Language Reference Shift Operators: >> and <<>
The right shift operator causes the bit pattern in the first operand
to be shifted right the number of bits specified by the second
operand. Bits vacated by the shift operation are zero-filled for
unsigned quantities. For signed quantities, the sign bit is propagated
into the vacated bit positions. The shift is a logical shift if the
left operand is an unsigned quantity; otherwise, it is an arithmetic
shift.
Le "contrat" est clair. J'intuite qu'il est le même pour toutes les
implémentations "complément à 2".
Loïc Joly <loic.actarus.joly@wanadoo.fr> typa:
Mickael Pointier wrote:
The value of E1 >> E2 is E1 rightshifted E2 bit positions. If E1 has
an unsigned type or if E1 has a signed type and a nonnegative value,
the value of the result is the integral part of the quotient of E1
divided by the quantity 2 raised to the power E2. If E1 has a signed
type and a negative value, the resulting value is
implementationdefined.
Ne pas confondre bug et non-conformité à la norme. Le bug est
pratiquement un "délit commercial", à juger par rapport à un contrat.
La norme dit "implementation defined", l'implémentation documente :
</MSDN VS.NET 2003 C++ Language Reference Shift Operators: >> and <<>
The right shift operator causes the bit pattern in the first operand
to be shifted right the number of bits specified by the second
operand. Bits vacated by the shift operation are zero-filled for
unsigned quantities. For signed quantities, the sign bit is propagated
into the vacated bit positions. The shift is a logical shift if the
left operand is an unsigned quantity; otherwise, it is an arithmetic
shift.
Le "contrat" est clair. J'intuite qu'il est le même pour toutes les
implémentations "complément à 2".
Loïc Joly typa:Mickael Pointier wrote:
The value of E1 >> E2 is E1 rightshifted E2 bit positions. If E1 has
an unsigned type or if E1 has a signed type and a nonnegative value,
the value of the result is the integral part of the quotient of E1
divided by the quantity 2 raised to the power E2. If E1 has a signed
type and a negative value, the resulting value is
implementationdefined.
Ne pas confondre bug et non-conformité à la norme. Le bug est
pratiquement un "délit commercial", à juger par rapport à un contrat.
La norme dit "implementation defined", l'implémentation documente :
</MSDN VS.NET 2003 C++ Language Reference Shift Operators: >> and <<>
The right shift operator causes the bit pattern in the first operand
to be shifted right the number of bits specified by the second
operand. Bits vacated by the shift operation are zero-filled for
unsigned quantities. For signed quantities, the sign bit is propagated
into the vacated bit positions. The shift is a logical shift if the
left operand is an unsigned quantity; otherwise, it is an arithmetic
shift.
Le "contrat" est clair. J'intuite qu'il est le même pour toutes les
implémentations "complément à 2".
"K. Ahausse" typa:Testez par vous même:
#include <stdio.h>
#include <conio.h>
void main()
{
int nValue;
printf("entrey la valeur -1024 et comparez le resultat entre debug
et
releasen");
scanf("%d",&nValue);
int nResult = ((nValue>>31)^nValue)>>4;
printf("Resultat %dn",nResult);
}
========================= > >>
Je pencherais pour un comportement non défini, et non pour un bug.
La norme defini-t-elle les valeurs signées binaires ? la rotation de ces
memes valeurs ?
Ne pouvant le tester par moi-même ( VC6, seulement), une solution serait
de
caster en unsigned :
int nResult = (( ((unsigned int) nValue) >>31)^nValue)>>4;
Extrait du post de Loïc Joly (et de C++98 5.8.3):
"...If E1 has a signed type and a negative value, the resulting value
is implementation defined."
Implementation defined behavior != undefined behavior (C++98 1.3.5 et
1.3.12)
Extrait de mon post précédent (et de la documentation de
l'implémentation, où le "behavior" est "defined") :
</MSDN VS.NET 2003 C++ Language Reference Shift Operators: >> and <<>
The right shift operator causes the bit pattern in the first operand
to be shifted right the number of bits specified by the second
operand. Bits vacated by the shift operation are zero-filled for
unsigned quantities. For signed quantities, the sign bit is propagated
into the vacated bit positions. The shift is a logical shift if the
left operand is an unsigned quantity; otherwise, it is an arithmetic
shift.
Microsoft Specific
The result of a right shift of a signed negative quantity is
implementation dependent. Although Microsoft C++ propagates the
most-significant bit to fill vacated bit positions, there is no
guarantee that other implementations will do likewise.
END Microsoft Specific
</MSDN VS.NET 2003 C++ Language Reference Shift Operators: >> and <<>
"K. Ahausse" <anonymous@discussions.microsoft.com> typa:
Testez par vous même:
#include <stdio.h>
#include <conio.h>
void main()
{
int nValue;
printf("entrey la valeur -1024 et comparez le resultat entre debug
et
releasen");
scanf("%d",&nValue);
int nResult = ((nValue>>31)^nValue)>>4;
printf("Resultat %dn",nResult);
}
========================= > >>
Je pencherais pour un comportement non défini, et non pour un bug.
La norme defini-t-elle les valeurs signées binaires ? la rotation de ces
memes valeurs ?
Ne pouvant le tester par moi-même ( VC6, seulement), une solution serait
de
caster en unsigned :
int nResult = (( ((unsigned int) nValue) >>31)^nValue)>>4;
Extrait du post de Loïc Joly (et de C++98 5.8.3):
"...If E1 has a signed type and a negative value, the resulting value
is implementation defined."
Implementation defined behavior != undefined behavior (C++98 1.3.5 et
1.3.12)
Extrait de mon post précédent (et de la documentation de
l'implémentation, où le "behavior" est "defined") :
</MSDN VS.NET 2003 C++ Language Reference Shift Operators: >> and <<>
The right shift operator causes the bit pattern in the first operand
to be shifted right the number of bits specified by the second
operand. Bits vacated by the shift operation are zero-filled for
unsigned quantities. For signed quantities, the sign bit is propagated
into the vacated bit positions. The shift is a logical shift if the
left operand is an unsigned quantity; otherwise, it is an arithmetic
shift.
Microsoft Specific
The result of a right shift of a signed negative quantity is
implementation dependent. Although Microsoft C++ propagates the
most-significant bit to fill vacated bit positions, there is no
guarantee that other implementations will do likewise.
END Microsoft Specific
</MSDN VS.NET 2003 C++ Language Reference Shift Operators: >> and <<>
"K. Ahausse" typa:Testez par vous même:
#include <stdio.h>
#include <conio.h>
void main()
{
int nValue;
printf("entrey la valeur -1024 et comparez le resultat entre debug
et
releasen");
scanf("%d",&nValue);
int nResult = ((nValue>>31)^nValue)>>4;
printf("Resultat %dn",nResult);
}
========================= > >>
Je pencherais pour un comportement non défini, et non pour un bug.
La norme defini-t-elle les valeurs signées binaires ? la rotation de ces
memes valeurs ?
Ne pouvant le tester par moi-même ( VC6, seulement), une solution serait
de
caster en unsigned :
int nResult = (( ((unsigned int) nValue) >>31)^nValue)>>4;
Extrait du post de Loïc Joly (et de C++98 5.8.3):
"...If E1 has a signed type and a negative value, the resulting value
is implementation defined."
Implementation defined behavior != undefined behavior (C++98 1.3.5 et
1.3.12)
Extrait de mon post précédent (et de la documentation de
l'implémentation, où le "behavior" est "defined") :
</MSDN VS.NET 2003 C++ Language Reference Shift Operators: >> and <<>
The right shift operator causes the bit pattern in the first operand
to be shifted right the number of bits specified by the second
operand. Bits vacated by the shift operation are zero-filled for
unsigned quantities. For signed quantities, the sign bit is propagated
into the vacated bit positions. The shift is a logical shift if the
left operand is an unsigned quantity; otherwise, it is an arithmetic
shift.
Microsoft Specific
The result of a right shift of a signed negative quantity is
implementation dependent. Although Microsoft C++ propagates the
most-significant bit to fill vacated bit positions, there is no
guarantee that other implementations will do likewise.
END Microsoft Specific
</MSDN VS.NET 2003 C++ Language Reference Shift Operators: >> and <<>
Salut.
J'ai un de mes collègues qui est tombé sur ce qui ressemble à un bug de
Visual.net (non présent dans Visual 6), mais bon, c'est peut-être bettement
que ce qu'il a fait à un comportement indéfini, donc je préfère demander ici
avant éventuellement de reporter le bug à qui de droit.
Salut.
J'ai un de mes collègues qui est tombé sur ce qui ressemble à un bug de
Visual.net (non présent dans Visual 6), mais bon, c'est peut-être bettement
que ce qu'il a fait à un comportement indéfini, donc je préfère demander ici
avant éventuellement de reporter le bug à qui de droit.
Salut.
J'ai un de mes collègues qui est tombé sur ce qui ressemble à un bug de
Visual.net (non présent dans Visual 6), mais bon, c'est peut-être bettement
que ce qu'il a fait à un comportement indéfini, donc je préfère demander ici
avant éventuellement de reporter le bug à qui de droit.