[Issue 3999] Enum equality to an int

d-bugmail at puremagic.com d-bugmail at puremagic.com
Thu Aug 25 02:19:40 PDT 2011


http://d.puremagic.com/issues/show_bug.cgi?id=3999



--- Comment #5 from bearophile_hugs at eml.cc 2011-08-25 02:19:30 PDT ---
One example of bug caused by the semantic sloppiness of D enums. This is
reduced code of a small game. The main contains a while that loops until the
game is finished.

The original version of this program was simpler, and instead of using the
GameState enum, it just used 0, 1 and -1 constants in the code.

So the original version of isFinished tests if winner() != -1. Later I have
used the enum GameState, that the winner function now returns. Bug I have
forgotten to update the isFinished() function too. The D language doesn't catch
that simple bug:


struct GameBoard {
    // ...
    enum GameState { inProgress, draw, humanWins, computerWins }

    GameState winner() {
        // this function used to return -1, 1, 0 values
        // ...
    }

    bool isFinished() {
        return winner() != -1; // not updated function!
        //return winner() != GameState.inProgress; // correct code!
    }
}
void main() {
    // ...
    Board game;

    while (!game.isFinished()) {
        // ...
    }
    // ...
}


In a bigger program it becomes hard to catch a similar bug (this bug was not
found also because of another waeak typing characteristic of D language: inside
isFinished it allowes you to compare an unsigned size_t value with -1, despite
-1 is statically visibly outside the range of possible unsigned values).

If I write similar code in C++11, it catches that bug:


enum class GameState {
    inProgress,
    draw,
    humanWins,
    computerWins
};
GameState winner() {
    return GameState::draw;
}
bool isFinished() {
    return winner() != -1; // line 11, error
}
int main() {}


G++ 4.6.0 outputs:

test.cpp: In function 'bool isFinished()':
test.cpp:11:25: error: no match for 'operator!=' in 'winner() != -0x000000001'


In D "final switches" where introduces right to avoid this class of bugs (if
you add an item to an enumeration, and you forget to add a case in a final
switch, the final switch will generate an error. This forces you at
compile-time to consider all cases, as pattern matching does in some functional
languages. Accepting enum conversions to ints causes similar bugs).

Please make named D enums strongly typed. Weak typing is better left to old
versions of the C language.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list