Поврежденное поведение примитивной программы на C на MacBook Pro, Windows XP, VS 2008 Express Edition
Я знаю, в это трудно поверить, но я на 100% серьезно отношусь к этому.
Когда я компилирую приведенный ниже код в Visual Studio 2008 Express Edition в режиме выпуска на своем MacBook Pro (Core 2 Duo P8600) с 32-разрядным пакетом обновления 3 (SP3) для Windows XP Professional, запускаю исполняемый файл, и printf запускается спорадически, как только я касаюсь тачпад (без шуток) - чего точно не должно случиться.
Кто-нибудь может воспроизвести ту же проблему на своем MacBook Pro (или любом другом ноутбуке)? Кто-нибудь может увидеть в списке сборки, в чем может быть проблема?
Я думаю, что драйвер тачпада каким-то образом управляет регистром, который отвечает за сравнение с плавающей запятой. С целыми числами проблема не возникает.
Любая идея, что здесь происходит, будет очень кстати.
#include <stdio.h>
int main()
{
while (true)
{
float x = 1.0f;
for (int i = 0; i < 50; i++)
{
if (0.0f < x)
x = 0.0f;
}
if (x == 1.0f)
printf("bad: %.2f\n", x);
}
return 0;
}
Вот листинг сборки для приведенного выше кода, созданного Visual Studio 2008 Express Edition:
; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.30729.01
TITLE c:\Dokumente und Einstellungen\azad\Desktop\WeirdProblem\main.cpp
.686P
.XMM
include listing.inc
.model flat
INCLUDELIB MSVCRT
INCLUDELIB OLDNAMES
PUBLIC ??_C@_0L@LNNNMCPH@bad?3?5?$CF?42f?6?$AA@ ; `string'
PUBLIC __real@00000000
PUBLIC __real@0000000000000000
PUBLIC __real@3f800000
PUBLIC _main
EXTRN __imp__printf:PROC
EXTRN __fltused:DWORD
; COMDAT ??_C@_0L@LNNNMCPH@bad?3?5?$CF?42f?6?$AA@
; File c:\dokumente und einstellungen\azad\desktop\weirdproblem\main.cpp
CONST SEGMENT
??_C@_0L@LNNNMCPH@bad?3?5?$CF?42f?6?$AA@ DB 'bad: %.2f', 0aH, 00H ; `string'
CONST ENDS
; COMDAT __real@00000000
CONST SEGMENT
__real@00000000 DD 000000000r ; 0
CONST ENDS
; COMDAT __real@0000000000000000
CONST SEGMENT
__real@0000000000000000 DQ 00000000000000000r ; 0
CONST ENDS
; COMDAT __real@3f800000
CONST SEGMENT
__real@3f800000 DD 03f800000r ; 1
; Function compile flags: /Ogtpy
CONST ENDS
; COMDAT _main
_TEXT SEGMENT
_x$3834 = -4 ; size = 4
_main PROC ; COMDAT
; 4 : {
push ebp
mov ebp, esp
and esp, -64 ; ffffffc0H
fld1
sub esp, 60 ; 0000003cH
fldz
push esi
fldz
mov esi, DWORD PTR __imp__printf
jmp SHORT $LN7@main
$LN43@main:
; 10 : {
; 11 : if (0.0f < x)
; 12 : x = 0.0f;
; 13 : }
; 14 :
; 15 : if (x == 1.0f)
fstp ST(0)
fxch ST(2)
$LN7@main:
fxch ST(2)
mov ecx, 10 ; 0000000aH
fst DWORD PTR _x$3834[esp+64]
fld DWORD PTR _x$3834[esp+64]
$LN5@main:
fcom ST(2)
fnstsw ax
test ah, 65 ; 00000041H
jne SHORT $LN4@main
fstp ST(0)
fxch ST(2)
fst DWORD PTR _x$3834[esp+64]
fld DWORD PTR _x$3834[esp+64]
fxch ST(1)
fxch ST(3)
fxch ST(1)
$LN4@main:
fcom ST(2)
fnstsw ax
test ah, 65 ; 00000041H
jne SHORT $LN14@main
fstp ST(0)
fxch ST(2)
fst DWORD PTR _x$3834[esp+64]
fld DWORD PTR _x$3834[esp+64]
fxch ST(1)
fxch ST(3)
fxch ST(1)
$LN14@main:
fcom ST(2)
fnstsw ax
test ah, 65 ; 00000041H
jne SHORT $LN15@main
fstp ST(0)
fxch ST(2)
fst DWORD PTR _x$3834[esp+64]
fld DWORD PTR _x$3834[esp+64]
fxch ST(1)
fxch ST(3)
fxch ST(1)
$LN15@main:
fcom ST(2)
fnstsw ax
test ah, 65 ; 00000041H
jne SHORT $LN16@main
fstp ST(0)
fxch ST(2)
fst DWORD PTR _x$3834[esp+64]
fld DWORD PTR _x$3834[esp+64]
fxch ST(1)
fxch ST(3)
fxch ST(1)
$LN16@main:
fcom ST(2)
fnstsw ax
test ah, 65 ; 00000041H
jne SHORT $LN17@main
fstp ST(0)
fxch ST(2)
fst DWORD PTR _x$3834[esp+64]
fld DWORD PTR _x$3834[esp+64]
fxch ST(1)
fxch ST(3)
fxch ST(1)
$LN17@main:
; 5 : while (true)
; 6 : {
; 7 : float x = 1.0f;
; 8 :
; 9 : for (int i = 0; i < 50; i++)
sub ecx, 1
jne $LN5@main
; 10 : {
; 11 : if (0.0f < x)
; 12 : x = 0.0f;
; 13 : }
; 14 :
; 15 : if (x == 1.0f)
fld ST(1)
fucomp ST(1)
fnstsw ax
test ah, 68 ; 00000044H
jp $LN43@main
fstp ST(2)
; 16 : printf("bad: %.2f\n", x);
sub esp, 8
fstp ST(2)
fstp ST(1)
fstp QWORD PTR [esp]
push OFFSET ??_C@_0L@LNNNMCPH@bad?3?5?$CF?42f?6?$AA@
call esi
; 17 : }
fld1
fldz
add esp, 12 ; 0000000cH
fldz
jmp $LN7@main
_main ENDP
_TEXT ENDS
END
2 ответа
Может иметь отношение к FPU и оптимизации. Это случится, если вы определите x
как volatile float
или скомпилировать с /O0
? Если это так, возможно, глючный драйвер изменяет состояние FPU.
Я не понимаю, как драйвер тачпада может производить такое поведение.
Я чувствую, что это какая-то проблема с оборудованием. Вы случайно не разогнали свой MacBook? Процессор может начать делать всякие странные вещи, как только вы разгоняете его (у Эрика Реймонда есть несколько военных историй, чтобы рассказать об этом). Если вы не разгоняете, возможно, ваш процессор просто перегревается? Может быть, стоит проверить вентиляционные отверстия. Или, может быть, это просто ненадежный процессор.
Если это процессор, почему это происходит только при касании сенсорной панели? Чистое предположение, но, возможно, утечка энергии с сенсорной панели понижает напряжение процессора, чтобы заставить его делать глупые вещи...