Поврежденное поведение примитивной программы на 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? Процессор может начать делать всякие странные вещи, как только вы разгоняете его (у Эрика Реймонда есть несколько военных историй, чтобы рассказать об этом). Если вы не разгоняете, возможно, ваш процессор просто перегревается? Может быть, стоит проверить вентиляционные отверстия. Или, может быть, это просто ненадежный процессор.

Если это процессор, почему это происходит только при касании сенсорной панели? Чистое предположение, но, возможно, утечка энергии с сенсорной панели понижает напряжение процессора, чтобы заставить его делать глупые вещи...

Другие вопросы по тегам