Я могу подтвердить то же поведение вашего кода, не относящегося к виртуальной машине, но, поскольку у меня нет виртуальной машины, я не тестировал часть виртуальной машины.
Однако компилятор, Clang и GCC, будет оценивать константу во время компиляции. Смотрите выходные данные сборки (используя gcc -O0 test.cpp -S
):
.file "test.cpp"
.section .rodata
.LC0:
.string "equal"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $.LC0, %edi
call puts
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1"
.section .note.GNU-stack,"",@progbits
Похоже, вы понимаете сборку, но ясно, что есть только строка "равно", нет "не равно". Таким образом, сравнение даже не выполняется во время выполнения, оно просто выводит «равно».
Я бы попробовал закодировать расчет и сравнение, используя сборку, и посмотреть, есть ли у вас такое же поведение. Если у вас другое поведение на виртуальной машине, то это способ, которым виртуальная машина выполняет вычисления.
ОБНОВЛЕНИЕ 1: (на основе «ОБНОВЛЕНИЕ 2» в первоначальном вопросе). Ниже показана выходная сборка gcc -O0 -S test.cpp
(для 64-битной архитектуры). В нем вы можете увидеть строку movabsq $4607182418800017408, %rax
дважды. Это будет для двух флагов сравнения, я не проверял, но я предполагаю, что значение $ 4607182418800017408 равно 1,1 в терминах с плавающей запятой. Было бы интересно скомпилировать это на ВМ, если вы получите тот же результат (две одинаковые строки), то ВМ будет делать что-то смешное во время выполнения, в противном случае это комбинация ВМ и компилятора.
main:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movabsq $4607182418800017408, %rax
movq %rax, -16(%rbp)
movabsq $4607182418800017408, %rax
movq %rax, -8(%rbp)
movsd -16(%rbp), %xmm1
movsd .LC1(%rip), %xmm0
addsd %xmm1, %xmm0
movsd -8(%rbp), %xmm2
movsd .LC1(%rip), %xmm1
addsd %xmm2, %xmm1
ucomisd %xmm1, %xmm0
jp .L6
ucomisd %xmm1, %xmm0
je .L7