3 ms·
In Pascal you can easily create such a type OneToFive = 1..5 It should inherit all the normal arithmetic, but does not allow values outside the range However,
by benibela 6y ago
In Pascal you can easily create such a type OneToFive = 1..5
It should inherit all the normal arithmetic, but does not allow values outside the range
However, these kind of types are causing a lot of problems.
You do arithmetic on them, get a value outside of the range, and then it throws an exception. And an unhandled exception crashes the program, which is often worse than an invalid value.
And it is slow when it has to check if the value is in the range after every arithmetic operation, so you can disable the range checking to make it faster. But then you get values outside the range without an error
The language also assumes everything can be initialized to zero. It just calls "memset" on a allocated memory, so it can be initialized quickly. So you often get values that are zero whatever the range is
And you cannot even check for that, because the compiler knows what values are valid. So if you want to check if the variable has a valid value and write (value >= 1 and value <= 5), the compiler knows it is supposed to be always true, and optimizes it away.
- 0xFluegel 6y ago> And an unhandled exception crashes the program, which is often worse than an invalid value. Please elaborate. Why is working with garbage better than not working at all? Would it not also rather make it easier to find these out-of-range cases with fuzzing?
- benibela 6y agoIt is better in GUI applications. You have 1% of code dealing with user data, and 99% of code doing other things For example, a text editor. If it crashes, you lose all your text since the last save, which is very bad. But the editor also does other things like playing animations when you click somewhere, a lowering button, or a show a rotating hourglass as mouse cursor. If it would show a wrong animation, that is completely irrelevant. Or it has syntax highlighting with a range type for possible user-defined colors. If it shows the wrong color, that is no big deal. But if you have a new version of the editor, adding more colors, and you use those colors in the user's setting, you cannot downgrade to an older version, because it would crash when it does not know the new colors. I just had an actual problem with such an exception when calling GetFileAttributes. It returns INVALID_FILE_ATTRIBUTES (unsigned 0xFFFFFFFF) on failure. But I was calling a wrapper around it, which casts it to a signed value and then return -1. Storing the return value in an unsigned variable and then comparing it to 0xFFFFFFFF gave me a range check error. But compiled with range checking disabled, it works perfectly fine.
- wtetzner 6y ago> It is better in GUI applications. Unless it's in that one percent of code that deals with user data, in which case it might be much better to just crash. Depending on what the GUI application is for, giving incorrect values could be very bad. I would think you could catch all exceptions at the top level, save a backup of whatever data the user has loaded, and then continue to crash normally.
- pydry 6y ago>You do arithmetic on them, get a value outside of the range, and then it throws an exception. And an unhandled exception crashes the program, which is often worse than an invalid value. IMO an exception (failing fast) is always better than an invalid value. Exceptions like these also excel at finding dangerous edge cases when paired with a decent test suite.
- jstimpfle 6y agoA problem that I see with these approaches (e.g. 1..5) is that the possible values are often not set in stone. This means that by using range constraints or similar, there is often an overspecification that can hurt down the road. Furthermore, the possible values differ from location to location as the values travel through the program. In that sense, the possible values are often underspecified / underconstrained, even though the specifications are already not simple. This is why I prefer to go with rather little constraints - in a compiled language, you have to specify the physical layout (8/16/32/64 bits?), and I try to specify not more than that in most cases. Then, so much safety can be achieved by placing asserts in strategic locations.