Waldek Hebisch wrote:
Frank Heckenbach wrote:
We should not. According to BP (the only documented reference I have about type-casts at all), there are two kinds of type-casts: Variable type-casts (which require variables, or rather "lvalues" and cast to types of the same size -- as for lvalues the size is well-defined), and value type-casts which apply to ordinal types (and pointers in MP) and which conserve ordinal values (or addresses).
I thing that BP really mixed different things together.
Yes, it might have been preferable to use different syntax for the two kinds of type-casts it supports, but now we have no choice. But at least there's no real conflict, as in the case where both casts are applicable -- casting an ordinal lvalue to an ordinal type of the same size, and using it as an rvalue -- both yield the same result.
I would say that there are two kinds of casts: raw cast, which just interpret storage (bit pattern) as a different type and
That's "variable type-casts" for BP. In BP, they're only allowed for lvalues, and I think that's good, since other expressions may not have a well-defined bit pattern, in particular size.
conversions, which may do some non-trivial computation.
That's not what BP type-casts do. Of course, some implicit conversions (Integer -> Real, Char -> String) which BP also does, could fall in this category.
But BP's "value type-casts" would then be a third category: They do not necessarily preserve storage (as they can cast between different sizes), but they do not do any non-trivial computations (only possibly extending/shrinking the size, and perhaps range-checking).
Additionaly, cast may silently "do the work", or they may serve as assertions that the value "really" is of different type.
Raw casts typically do not signal errors, still one could signal them for invalid or out of range values.
I see a few different uses of casts:
- for low-level programming, here we want raw cast and it should not matter if the value converted is variable or constant.
It's not really about being variable or constant. `protected' and `const' parameters can be casted, even variables declared with `attribute (const)'. It's more about "lvalues".
Actually, the only bad case seem to be set constants, since we can extend/truncate integers to desired size and other constansts have well defined size. So forbiding all constansts (even typed!) seem to harsh for me.
"Typed constants" in the BP sense are really lvalues, so do you mean EP structured values?
I'm not convinced. E.g., when truncating a (signed) integer, do you use a signed or unsigned shorte type? Both will clip some values, but different ones.
And you forgot reals. "Casting" a real to another type may on some platforms preserve the bit pattern, on others do a conversion to another size (which usually changes the bit pattern quite a bit) and preserve that, and on others fail completely as no such sized real type is available.
You also forgot string constants. Should they be represented as fix-strings or string schemata, possibly short strings in the future?
I think the general principle is just that constants do not (necessarily) carry enough memory-layout information. They represent values, and values can be stored in different forms.
As you say, it's usually used for low-level programming, and low-level programming should be the exception in Pascal, I don't feel the need to simplify it (given the problems). After all, the additional "difficulty" with the current (BP) system is only having to assign the value to a temporary variable before the type-cast.
- Our current signed/unsigned problems clearly show need for explicit conversions in arithmetic expressions.
But these are value type casts, in that they don't change the numeric value, and they're range-safe. Thus they're equivalent to the standard construct of assigning to a temporary variable of the target type (without needing any type-cast).
It make some sense to allow such conversions also for sets (but I do not insists).
By "such conversion" I suppose then you mean converting a set value to a compatible set type, preserving the value (elements)? What could this ever be useful for? (For integers we have different sizes and overflow problems, but set operations always choose fitting result types anyway.)
- Cast as type assertions are frequently used in OOP, where one wants to treat an object as object of different class (handled by `as')
Yes. That's a safe operator as it checks before conversion and allows only valid "casts".
Frank