It does: whenever you perform an explicit typecast, the compiler will at most warn that what you are doing is wrong (unless it has no idea how to perform the explicit typecast at all, like trying to typecast records of different sizes). It won't forbid you to do it. That's all what checks can do: warn, or forbid something.
It would be _great_ if it gave at least a warning or downright forbid it instead of silently producing incorrect code.
I really don't know anymore how else I can explain to you that there is nothing arbitrary about the array example you are so hung up on.
At least we've managed to have a meeting of the minds on that one.
Maybe this:
type
arrayrange = 0..0;
tarray1 = array[arrayrange] of byte;
tarray2 = array[0..0] of byte;
The above declarations are equivalent. Declaring an array type always implies declaring two types: a range/index type, and the array type itself.
So far, so good but, as you, yourself pointed out below, one of those types is an
implied type, not a declared type and, I'm sure you know I am referring to the implied type of the array range.
When you index an array, the index will always be converted to the range type. This is not an explicit type conversion, but an implicit type conversion.
This is where things start going awfully wrong. The index has a
declared type and the compiler, in the specific example we are both thinking about, chose to
override an explicit type declaration with an
incorrect data type assumption it made.
There are two things that are awfully wrong with that:
1. an implied type cannot override a declared type. That doesn't make any sense. It's illogical, unjustifiable and unreasonable.
2. a data type
cannot be derived from the constant zero. It is beyond wrong for the compiler to incorrectly presume that zero implies an unsigned type. It is mathematically wrong.
and just as bonuses, Delphi, various flavors of C and various flavors of C++ don't override a variable's declared type with what is actually a _presumed_ type and, don't produce a different result depending on the bitness as FPC does. That alone, should be a clear tell-tale sign that something isn't the way it should be.
The compiler will not perform any range checking for this conversion, unless range checking is enabled.
It did worse than that, it
forced a signed data type to become an unsigned type based on the completely incorrect assumption that the constant zero indicates a Pascal unsigned type, which it does not.
This conversion does the following things:
* it checks for type compatibility between the index you passed and the declared type. This is what causes a compile-time type conversion error if you try to index an array with e.g. an ansistring. If no implicit type conversion would be inserted, such errors would not be caught.
* it performs a range check if range checking is enabled
That's all fine and dandy but, the conversion and the result is driven by the declared types of the _variables_ and in the cases where the constant drives the conversion, it _promotes_ the variables to a superset type e.g int32 to int64. A constant can never demote a variable's declared type which is what FPC did in the specific case we are talking about.
In the above example, it is hence assumed to contain a value in the range 0..0. So the compiler will generate code that is valid as long as the index contains a value within this range. At this point, the compiler has no clue any more about what the original type of the index variable was.
The compiler cannot assume that a variable does or does not contain the value that the range denotes. It can check that the variable is in the range if and only if the programmer has told it to do so. Otherwise, the compiler's job is to calculate the address referenced using the old "address(array_variable) + (n * elementsize)" where n is the programmer specified index not some value the compiler decided to use because it mistakenly believes that the constant zero is only a member of the unsigned Pascal datatypes (we both know that zero belongs to both, signed and unsigned types. That alone tears down every argument you've presented to justify that FPC bug.)
Again, this is unrelated to range checking or explicit type casts. And it is not arbitrary, because it the compiler is using literally the range type that the programmer told the compiler to use for this array.
I'm guessing that applies to the Boolean thing this thread is actually about. I have no comment on that.
It would be really nice if the FPC bug, we both know which one, got fixed. I'll throw in a Boolean48 in the deal if that's what it takes.