Bug im 64-Bit Compiler?



  • Hallo
    Ursprünglich ist das Problem in meiner Schachengine aufgetreten. Ich habe den Code soweit wie möglich auf das Problem reduziert. Daher ist der folgende Code sinnlos und dient nur zu Untersuchung dieses Compilerproblems.

    Die Ausgabe dieses Programmes ist abhängig vom Compiler bzw. den Flags des Compilers. Unter allen von mir getesteten Compilern gibt das Programm auf der Konsole folgende korrekten Werte aus:

    value........50100 
    temp.........50100
    

    Nur im 64-Bit Release Modus unter Visual Studio 2010 Professional mit den optimierenden Flags und Ob1 oder Ob2 (wichtig) kommt es zu folgender Bildschirmausgabe, welche falsch ist:

    value........50000 
    temp.........50000
    

    Hier der fehlerproduzierende Code. Am besten ein neues Projekt unter Microsoft Visual Studio 2010 Professional anlegen und als x64 Release mit Ob2 kompilieren lassen. Das Einfügen von weiteren printfs() ist nicht möglich, da der Fehler dann wieder verschwindet.

    #include <stdio.h>
    
    const int IS_ENPASSANT = 1 << 15;
    
    struct move_info_c { int move, value; };
    struct board_c { int piece_on[64]; } B;
    
    inline int move_to(int move) { return move & 63; }
    inline int move_from(int move) { return (move >> 6) & 63; }
    inline int move_is_enpassant(int move) { return (move & IS_ENPASSANT) != 0; }
    inline int make_enpassant(int from, int to) { return to | (from << 6) | IS_ENPASSANT; }
    inline int piece_on_square(int square) { return B.piece_on[square]; }
    inline int move_is_capture(int move) { return (piece_on_square(move_to(move)) != 6) || move_is_enpassant(move); }
    inline int move_piece(int move) { return piece_on_square(move_from(move)); }
    inline int move_piece_captured(int move) { return move_is_enpassant(move) ? 0 : piece_on_square(move_to(move)); }
    
    inline int piece_value_midgame(int piece) {
        int piece_value_mg[7] = {100, 300, 400, 500, 900, 1000, 0};
        return piece_value_mg[piece];
    }
    
    void initialize() {
        for (int square = 0; square < 64; square++) B.piece_on[square] = 6;
        B.piece_on[28] = B.piece_on[29] = 0;
    }
    
    class sort_c {
    public:
        sort_c();
        move_info_c * last_move, move_list[256];
    };
    
    sort_c::sort_c() {
        move_list[0].move = make_enpassant(28, 21);
        move_info_c * current = move_list;
        int move = current->move, value = 0, temp = 0;
    
        if (value < 0) current->value = value;
        else if (move_is_capture(move)) {
         temp = 50000 + piece_value_midgame(move_piece_captured(move)) - move_piece(move);
         current->value = temp;
        }
        else current->value = 0;
    
        printf_s("value...........%d\n", current->value);
        printf_s("temp............%d\n", temp);
    }
    
    int main() {
      initialize();
      sort_c s;
      return 0;
    }
    

Anmelden zum Antworten