Scott Moore wrote:
Waldek Hebisch wrote:
Frank Heckenbach wrote:
Waldek Hebisch wrote:
Frank Heckenbach wrote:
As I said, I see the main problems in C interfaces (which so far rely on `Integer = int', while most other places really should not really on exact type sizes etc.). So *if* we change it, we should only change one type, something like `Integer = "undefined" in C', and `CInteger' (or whatever) = `int', so C interfaces would only have to s/Integer/CInteger/g. (And similar for `Cardinal'/`Word', even if nonstandard, but so we keep the fact that `Integer' and `Cardinal' have the same size.)
Of course, we'd also need a transition period here -- add `CInteger' now, let everyone change their interfaces (using GPC-version conditionals to avoid breaking compatibility with older GPCs), sometime change `Integer'. Unpleasant indeed ...
Let me try to estimate impact. AFAICS candidate for change are:
m68k 16 --> 32
and 64 bit targets:
alpha, s390x, ia64, ppc64, pa64, sparc64, mips64, sh, amd64
While other targets also would be forced to change type names, since the types would remain the same the change shuild be painless for them.
I see it a bit differently. I don't like to use a "wrong" type (i.e., `Integer' for `int' when it's actually `long', just because it happens to match on most platforms). In fact, to me it means that such instances will be harder to find for people (most have no access to a 64 bit platform).
But I agree that if we change it, we should do it quickly. Some arguments for and against the change have been given, but I'm still undecided (or rather, I personally wouldn't mind either way).
If we change it, we must agree on which changes exactly -- as I said, I propose `CInteger', `CCardinal', `CWord'(?) as equivalent to `[unsigned] int', and `Integer', `Cardinal', `Word' to be equivalent to `[unsigned] long int', at least on some platforms (Waldek seems to know better, which ones). This would keep the impact on C interfaces minimal AFAICS.
I propose to make `Integer' equivalent to `PtrInt', `Cardinal' to `PtrCard', `Word' to `PtrWord' (so also `PtrCard'). And `CInteger', `CCardinal', `CWord' should be equivalent to `[unsigned] int'.
Why: `PtrInt' should be of correct size as index of any array,, so there is no need to special case (C `long' may be to big or even to small). On the other hand on most platforms `PtrInt' is of the same size as C `int', so the impact is limited (as I wrote above).
I agree. (BTW, you mentioned some 8 and 16 bit targets, Waldek. Is this change also ok there, or do we need exceptions for them? I don't know details about any of them.)
I've just talked with Peter, and he also agrees.
The changes in the compiler are not difficult, of course. We see the most effort in changing C interfaces. I suggest something like this:
{$if __GPC_RELEASE__ < 20040801} type CInteger = Integer; CCardinal = Cardinal; CWord = Word; {$endif}
And replace `Integer', `Cardinal' and `Word' in the declarations with `C...'.
With the above conditional, the interfaces will keep working with existing GPC releases, and the change can be made already now (as soon as we've agreed on this, of course), so this should be least painful.
Eike, if you're reading this, since you wrote a lot of C interfaces: Is this OK with you?
The bottom line is, is GPC going to be a Pascal, or is it going to be a C look-alike ? The traditions and the standard for Pascal are explicit: integer is supposed to be the largest size that does not carry extra cost on the target machine. Specifying smaller sizes is clearly the scope of subranges, specification of larger types (like double precision) is not covered by either the original or standardized languages (which is not the same thing as non-existent).
Well, in a strictly standard compiler (such as GPC with `--classic-pascal' or `--extended-pascal') it's the same thing.
Pascal gives methods for specifying the exact type in an (extremely) portable way.
Not really. The standards do not specify type sizes in any way. Subranges can have the same or a smaller size than `Integer'. You might prefer the latter, I do the former. (For several reasons, (a) efficiency, especially on processors without built-in sub-word operations, (b) conceptually, I like to consider subranges as the same type as the original (i.e., the type of the bounds), with additional constraints; in the same way I could imagine subsets of other types, such as Real (but I don't want to go into this now), (c) with enum types, having types of different sizes would add unnecessary (IMHO) complexity).
Somewhere it became normal with many Pascals to adopt C's method instead, despite the fact that it is less portable (ie, every size has a predefined, labeled type).
Of course, I don't like this method at all. But we have to consider different purposes:
- Types of exact sizes (e.g., for file formats, though there are other considerations, such as endianness): GPC has `attribute size' here, and since neither C nor standard Pascal really have something like this at all, IMHO it's the best we can get.
- C compatibility types (needed in interfaces, of course). Here we have to follow the C model, but we're free to choose our names (such as `CInteger' in the proposed model).
- Types to hold certain ranges of values which should be handled efficiently, without caring about storage details. That's where subranges are best suited.
- etc. (there may be more purposes to consider when choosing types) ...
Even that aside, "dragging" integer or int is a loosing strategy even in C. It puts off the inevitable change to the larger size until tomorrow, meaning that programmers have more time to entrench programs using the wrong size.
BTW, I'm not sure that C ABIs will actually change in the future. Maybe C programmers will simply become used to using `long' almost everywhere, just like programmers of Borland Pascal and, especially, compatible 32 bit compilers, use `LongInt' regularly ...
Only the slow realization that the natural word width of the (by then most common) machine is being wasted counters that, and the result is programmers distrusting the int or integer type, and instead forcing more use of specifically sized types with special labels, furthering the scattering of dependencies.
Yes, I know I am being a bit preachy on the subject, but its an important one.
In fact, in C it might not even be regarded as a problem since `long' is a built-in type just as well as `int'.
But in Pascal `Integer' has a special status, so IMHO it's right to take the issue seriously.
And I think we agree on Waldek's proposal, don't we?
Frank