Tout est bien plus sérieux. Voici un exemple à tester:
#include <iostream>
int main()
{
std::cout << "-3/3u*3 = " << int(-3/3u*3) << "\n";
}
Vous pouvez voir le résultat ici .
Ou essayez de jouer avec cet exemple ici ou ici .
En fait, je n'ai pas pu trouver au moins un compilateur C ++ qui produirait un résultat autre que -4. Même l'ancien GCC-4.1.2 , clang-3.0.0 ou Borland C 1992 . J'ai également remarqué que le résultat est le même pour les constantes de compilation et d'exécution.
Je suggère d'examiner attentivement le résultat de l'expression -3/3u*3
.
Si nous supprimons la conversion au type int
dans l'exemple ci-dessus, nous obtenons 4294967292
ou 0xFFFFFFF(-4)
. Il s'avère que le compilateur considère en fait le résultat comme non signé et égal 4294967292
. Jusqu'à présent, j'étais fermement convaincu que si un type signé est utilisé dans une expression, le résultat sera signé. C'est logique.
, , :
int main()
{
volatile unsigned B = 3;
int A = -3/B*3;
}
x86-64 clang 12.0.0 , , -3
:
mov dword ptr [rbp - 4], 3 // B = 3
mov ecx, dword ptr [rbp - 4]
mov eax, 4294967293
xor edx, edx
div ecx // !!
imul eax, eax, 3 //
mov dword ptr [rbp - 8], eax
x64 msvc v19.28 :
mov DWORD PTR B$[rsp], 3 // B = 3
mov eax, DWORD PTR B$[rsp]
mov DWORD PTR tv64[rsp], eax
xor edx, edx
mov eax, -3 ; fffffffdH
mov ecx, DWORD PTR tv64[rsp]
div ecx
imul eax, eax, 3
mov DWORD PTR A$[rsp], eax
, div
. , , imul
. . , . idiv
, .
, 4294967293
3 : 4294967293 = 1431655764 * 3 + 1
1431655764
3, 4294967292
-4
. , 4294967293
-3, , .
- .
- , (add
sub
). ( ) . add
( sub
) ( - ). . . . . (idiv
) (div
) (imul
mul
).
, , , . : msvc, gcc, clang. , . , .
Otherwise, if the unsigned operand's conversion rank is greater or equal to the conversion rank of" "the signed operand, the signed operand is converted to the unsigned operand's type.
, , .
: "the signed operand is converted to the unsigned operand's type"!! , , !! : "the unsigned operand is converted to the signed operand's type", . -3
?? .
!
int main()
{
volatile unsigned B = 3;
int C = -3*B;
}
:
mov dword ptr [rbp - 4], 3 mov eax, dword ptr [rbp - 4] imul eax, eax, 4294967293 mov dword ptr [rbp - 8], eax
. .
, - . .
! !
, , , , , ( , , ) , , , . . .
, :
? ++ , . , .
. .
int main()
{
const unsigned a[] = {3,4,5,6,7};
unsigned p = (&a[0] - &a[3])/3u*3; // -3
unsigned b = -3/3u*3; // -4
}
, , , , ( ), - , -4
-3
, Boeing 737 MAX?
, ++ , , , , .
FDIV
, 2000- FDIV
. 5 - . !!
. . .
5- ! , , ! -4
-3
-3
4294967292
! ! .
, . , . -4 , ? , ++ ? , ? , , , !
, , , , , , . , , - .
: "Signed value is intentionally converted to unsigned value. Sorry for crashing one more airplane. Have a nice flight!" , .
, . . . .
() () .
- : , 5. ?
- : , . ! ! 5, .
- : ?? _. . , , -4 ? - : ! ++ , , . -4 - , . - : . , , ++. - : . ++, ++ . , , ! ++ , , ! , , ! - : . .